bbfe8b3
From b96ff1fd9e94772fde7b58fd69969d1a1c87eb6d Mon Sep 17 00:00:00 2001
bbfe8b3
From: Dave Young <dyoung@redhat.com>
bbfe8b3
Date: Tue, 27 Feb 2018 10:04:51 +0000
bbfe8b3
Subject: [PATCH 07/31] Copy secure_boot flag in boot params across kexec
bbfe8b3
 reboot
bbfe8b3
bbfe8b3
Kexec reboot in case secure boot being enabled does not keep the secure
bbfe8b3
boot mode in new kernel, so later one can load unsigned kernel via legacy
bbfe8b3
kexec_load.  In this state, the system is missing the protections provided
bbfe8b3
by secure boot.
bbfe8b3
bbfe8b3
Adding a patch to fix this by retain the secure_boot flag in original
bbfe8b3
kernel.
bbfe8b3
bbfe8b3
secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the
bbfe8b3
stub.  Fixing this issue by copying secure_boot flag across kexec reboot.
bbfe8b3
bbfe8b3
Signed-off-by: Dave Young <dyoung@redhat.com>
bbfe8b3
Signed-off-by: David Howells <dhowells@redhat.com>
bbfe8b3
Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
bbfe8b3
cc: kexec@lists.infradead.org
bbfe8b3
---
bbfe8b3
 arch/x86/kernel/kexec-bzimage64.c | 1 +
bbfe8b3
 1 file changed, 1 insertion(+)
bbfe8b3
bbfe8b3
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
bbfe8b3
index fb095ba0c02f..7d0fac5bcbbe 100644
bbfe8b3
--- a/arch/x86/kernel/kexec-bzimage64.c
bbfe8b3
+++ b/arch/x86/kernel/kexec-bzimage64.c
bbfe8b3
@@ -179,6 +179,7 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
bbfe8b3
 	if (efi_enabled(EFI_OLD_MEMMAP))
bbfe8b3
 		return 0;
bbfe8b3
bbfe8b3
+	params->secure_boot = boot_params.secure_boot;
bbfe8b3
 	ei->efi_loader_signature = current_ei->efi_loader_signature;
bbfe8b3
 	ei->efi_systab = current_ei->efi_systab;
bbfe8b3
 	ei->efi_systab_hi = current_ei->efi_systab_hi;
bbfe8b3
-- 
bbfe8b3
2.14.3
bbfe8b3
Jeremy Cline c8f9da6
From b5123d0553f4ed5e734f6457696cdd30228d1eee Mon Sep 17 00:00:00 2001
bbfe8b3
From: David Howells <dhowells@redhat.com>
bbfe8b3
Date: Tue, 27 Feb 2018 10:04:55 +0000
bbfe8b3
Subject: [PATCH 29/31] efi: Add an EFI_SECURE_BOOT flag to indicate secure
bbfe8b3
 boot mode
bbfe8b3
bbfe8b3
UEFI machines can be booted in Secure Boot mode.  Add an EFI_SECURE_BOOT
bbfe8b3
flag that can be passed to efi_enabled() to find out whether secure boot is
bbfe8b3
enabled.
bbfe8b3
bbfe8b3
Move the switch-statement in x86's setup_arch() that inteprets the
bbfe8b3
secure_boot boot parameter to generic code and set the bit there.
bbfe8b3
bbfe8b3
Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
bbfe8b3
Signed-off-by: David Howells <dhowells@redhat.com>
bbfe8b3
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
bbfe8b3
cc: linux-efi@vger.kernel.org
Jeremy Cline c8f9da6
Signed-off-by: Jeremy Cline <jcline@redhat.com>
bbfe8b3
---
Jeremy Cline c8f9da6
 arch/x86/kernel/setup.c           | 14 +-----------
bbfe8b3
 drivers/firmware/efi/Makefile     |  1 +
Jeremy Cline c8f9da6
 drivers/firmware/efi/secureboot.c | 38 +++++++++++++++++++++++++++++++
Jeremy Cline c8f9da6
 include/linux/efi.h               | 18 ++++++++++-----
Jeremy Cline c8f9da6
 4 files changed, 52 insertions(+), 19 deletions(-)
bbfe8b3
 create mode 100644 drivers/firmware/efi/secureboot.c
bbfe8b3
bbfe8b3
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
Jeremy Cline c8f9da6
index b74e7bfed6ab..7da1712c89c9 100644
bbfe8b3
--- a/arch/x86/kernel/setup.c
bbfe8b3
+++ b/arch/x86/kernel/setup.c
Jeremy Cline c8f9da6
@@ -1158,19 +1158,7 @@ void __init setup_arch(char **cmdline_p)
bbfe8b3
 	/* Allocate bigger log buffer */
bbfe8b3
 	setup_log_buf(1);
Jeremy Cline c8f9da6
 
bbfe8b3
-	if (efi_enabled(EFI_BOOT)) {
bbfe8b3
-		switch (boot_params.secure_boot) {
bbfe8b3
-		case efi_secureboot_mode_disabled:
bbfe8b3
-			pr_info("Secure boot disabled\n");
bbfe8b3
-			break;
bbfe8b3
-		case efi_secureboot_mode_enabled:
bbfe8b3
-			pr_info("Secure boot enabled\n");
bbfe8b3
-			break;
bbfe8b3
-		default:
bbfe8b3
-			pr_info("Secure boot could not be determined\n");
bbfe8b3
-			break;
bbfe8b3
-		}
bbfe8b3
-	}
bbfe8b3
+	efi_set_secure_boot(boot_params.secure_boot);
Jeremy Cline c8f9da6
 
bbfe8b3
 	reserve_initrd();
Jeremy Cline c8f9da6
 
bbfe8b3
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
Jeremy Cline c8f9da6
index 5f9f5039de50..7a0a6378203e 100644
bbfe8b3
--- a/drivers/firmware/efi/Makefile
bbfe8b3
+++ b/drivers/firmware/efi/Makefile
bbfe8b3
@@ -24,6 +24,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP)		+= fake_mem.o
bbfe8b3
 obj-$(CONFIG_EFI_BOOTLOADER_CONTROL)	+= efibc.o
bbfe8b3
 obj-$(CONFIG_EFI_TEST)			+= test/
bbfe8b3
 obj-$(CONFIG_EFI_DEV_PATH_PARSER)	+= dev-path-parser.o
bbfe8b3
+obj-$(CONFIG_EFI)			+= secureboot.o
bbfe8b3
 obj-$(CONFIG_APPLE_PROPERTIES)		+= apple-properties.o
Jeremy Cline c8f9da6
 
bbfe8b3
 arm-obj-$(CONFIG_EFI)			:= arm-init.o arm-runtime.o
bbfe8b3
diff --git a/drivers/firmware/efi/secureboot.c b/drivers/firmware/efi/secureboot.c
bbfe8b3
new file mode 100644
bbfe8b3
index 000000000000..9070055de0a1
bbfe8b3
--- /dev/null
bbfe8b3
+++ b/drivers/firmware/efi/secureboot.c
bbfe8b3
@@ -0,0 +1,38 @@
bbfe8b3
+/* Core kernel secure boot support.
bbfe8b3
+ *
bbfe8b3
+ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
bbfe8b3
+ * Written by David Howells (dhowells@redhat.com)
bbfe8b3
+ *
bbfe8b3
+ * This program is free software; you can redistribute it and/or
bbfe8b3
+ * modify it under the terms of the GNU General Public Licence
bbfe8b3
+ * as published by the Free Software Foundation; either version
bbfe8b3
+ * 2 of the Licence, or (at your option) any later version.
bbfe8b3
+ */
bbfe8b3
+
bbfe8b3
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
bbfe8b3
+
bbfe8b3
+#include <linux/efi.h>
bbfe8b3
+#include <linux/kernel.h>
bbfe8b3
+#include <linux/printk.h>
bbfe8b3
+
bbfe8b3
+/*
bbfe8b3
+ * Decide what to do when UEFI secure boot mode is enabled.
bbfe8b3
+ */
bbfe8b3
+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
bbfe8b3
+{
bbfe8b3
+	if (efi_enabled(EFI_BOOT)) {
bbfe8b3
+		switch (mode) {
bbfe8b3
+		case efi_secureboot_mode_disabled:
bbfe8b3
+			pr_info("Secure boot disabled\n");
bbfe8b3
+			break;
bbfe8b3
+		case efi_secureboot_mode_enabled:
bbfe8b3
+			set_bit(EFI_SECURE_BOOT, &efi.flags);
bbfe8b3
+			pr_info("Secure boot enabled\n");
bbfe8b3
+			break;
bbfe8b3
+		default:
bbfe8b3
+			pr_warning("Secure boot could not be determined (mode %u)\n",
bbfe8b3
+				   mode);
bbfe8b3
+			break;
bbfe8b3
+		}
bbfe8b3
+	}
bbfe8b3
+}
bbfe8b3
diff --git a/include/linux/efi.h b/include/linux/efi.h
Jeremy Cline c8f9da6
index 100ce4a4aff6..62361b647a75 100644
bbfe8b3
--- a/include/linux/efi.h
bbfe8b3
+++ b/include/linux/efi.h
Jeremy Cline c8f9da6
@@ -1155,6 +1155,14 @@ extern int __init efi_setup_pcdp_console(char *);
bbfe8b3
 #define EFI_DBG			8	/* Print additional debug info at runtime */
bbfe8b3
 #define EFI_NX_PE_DATA		9	/* Can runtime data regions be mapped non-executable? */
bbfe8b3
 #define EFI_MEM_ATTR		10	/* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
bbfe8b3
+#define EFI_SECURE_BOOT		11	/* Are we in Secure Boot mode? */
bbfe8b3
+
bbfe8b3
+enum efi_secureboot_mode {
bbfe8b3
+	efi_secureboot_mode_unset,
bbfe8b3
+	efi_secureboot_mode_unknown,
bbfe8b3
+	efi_secureboot_mode_disabled,
bbfe8b3
+	efi_secureboot_mode_enabled,
bbfe8b3
+};
Jeremy Cline c8f9da6
 
bbfe8b3
 #ifdef CONFIG_EFI
bbfe8b3
 /*
16332ac
@@ -1198,6 +1206,8 @@ static inline bool efi_enabled(int feature)
16332ac
 extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
16332ac
bbfe8b3
 extern bool efi_is_table_address(unsigned long phys_addr);
Jeremy Cline c8f9da6
+
bbfe8b3
+extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode);
bbfe8b3
 #else
bbfe8b3
 static inline bool efi_enabled(int feature)
bbfe8b3
 {
16332ac
@@ -1216,6 +1226,8 @@ static inline bool efi_is_table_address(unsigned long phys_addr)
bbfe8b3
 {
16332ac
 	return false;
bbfe8b3
 }
Jeremy Cline c8f9da6
+
bbfe8b3
+static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {}
bbfe8b3
 #endif
Jeremy Cline c8f9da6
 
bbfe8b3
 extern int efi_status_to_err(efi_status_t status);
Jeremy Cline c8f9da6
@@ -1577,12 +1589,6 @@ efi_status_t efi_setup_gop(efi_system_table_t *sys_table_arg,
bbfe8b3
 bool efi_runtime_disabled(void);
bbfe8b3
 extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
Jeremy Cline c8f9da6
 
bbfe8b3
-enum efi_secureboot_mode {
bbfe8b3
-	efi_secureboot_mode_unset,
bbfe8b3
-	efi_secureboot_mode_unknown,
bbfe8b3
-	efi_secureboot_mode_disabled,
bbfe8b3
-	efi_secureboot_mode_enabled,
bbfe8b3
-};
bbfe8b3
 enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table);
Jeremy Cline c8f9da6
 
bbfe8b3
 #ifdef CONFIG_RESET_ATTACK_MITIGATION
bbfe8b3
-- 
Jeremy Cline c8f9da6
2.19.1
bbfe8b3
bbfe8b3
From d78bf678059f83e22bec8ada1a448e22b9b90203 Mon Sep 17 00:00:00 2001
bbfe8b3
From: David Howells <dhowells@redhat.com>
bbfe8b3
Date: Tue, 27 Feb 2018 10:04:55 +0000
bbfe8b3
Subject: [PATCH 30/31] efi: Lock down the kernel if booted in secure boot mode
bbfe8b3
bbfe8b3
UEFI Secure Boot provides a mechanism for ensuring that the firmware will
bbfe8b3
only load signed bootloaders and kernels.  Certain use cases may also
bbfe8b3
require that all kernel modules also be signed.  Add a configuration option
bbfe8b3
that to lock down the kernel - which includes requiring validly signed
bbfe8b3
modules - if the kernel is secure-booted.
bbfe8b3
bbfe8b3
Signed-off-by: David Howells <dhowells@redhat.com>
bbfe8b3
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
bbfe8b3
cc: linux-efi@vger.kernel.org
bbfe8b3
---
bbfe8b3
 arch/x86/kernel/setup.c |  6 ++++--
bbfe8b3
 fs/debugfs/inode.c      |  2 +-
bbfe8b3
 security/Kconfig        | 14 ++++++++++++++
bbfe8b3
 security/lock_down.c    |  5 +++++
bbfe8b3
 4 files changed, 20 insertions(+), 3 deletions(-)
bbfe8b3
bbfe8b3
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
bbfe8b3
index a7c240f00d78..1277d1857c5c 100644
bbfe8b3
--- a/arch/x86/kernel/setup.c
bbfe8b3
+++ b/arch/x86/kernel/setup.c
bbfe8b3
@@ -64,6 +64,7 @@
bbfe8b3
 #include <linux/dma-mapping.h>
bbfe8b3
 #include <linux/ctype.h>
bbfe8b3
 #include <linux/uaccess.h>
bbfe8b3
+#include <linux/security.h>
bbfe8b3
bbfe8b3
 #include <linux/percpu.h>
bbfe8b3
 #include <linux/crash_dump.h>
bbfe8b3
@@ -997,6 +998,8 @@ void __init setup_arch(char **cmdline_p)
bbfe8b3
 	if (efi_enabled(EFI_BOOT))
bbfe8b3
 		efi_init();
bbfe8b3
bbfe8b3
+	efi_set_secure_boot(boot_params.secure_boot);
bbfe8b3
+
bbfe8b3
 	init_lockdown();
bbfe8b3
bbfe8b3
 	dmi_scan_machine();
bbfe8b3
@@ -1150,8 +1154,6 @@ void __init setup_arch(char **cmdline_p)
bbfe8b3
 	/* Allocate bigger log buffer */
bbfe8b3
 	setup_log_buf(1);
bbfe8b3
bbfe8b3
-	efi_set_secure_boot(boot_params.secure_boot);
bbfe8b3
-
bbfe8b3
 	reserve_initrd();
bbfe8b3
bbfe8b3
 	acpi_table_upgrade();
bbfe8b3
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
bbfe8b3
index ce261e1765ff..7aff55b309a6 100644
bbfe8b3
--- a/fs/debugfs/inode.c
bbfe8b3
+++ b/fs/debugfs/inode.c
bbfe8b3
@@ -40,7 +40,7 @@ static bool debugfs_registered;
bbfe8b3
 static int debugfs_setattr(struct dentry *dentry, struct iattr *ia)
bbfe8b3
 {
bbfe8b3
 	if ((ia->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) &&
bbfe8b3
-	    kernel_is_locked_down("debugfs"))
bbfe8b3
+	    kernel_is_locked_down("changing perms in debugfs"))
bbfe8b3
 		return -EPERM;
bbfe8b3
 	return simple_setattr(dentry, ia);
bbfe8b3
 }
bbfe8b3
diff --git a/security/Kconfig b/security/Kconfig
bbfe8b3
index 461d5acc3616..13fdada1ffc2 100644
bbfe8b3
--- a/security/Kconfig
bbfe8b3
+++ b/security/Kconfig
bbfe8b3
@@ -248,6 +248,20 @@ config ALLOW_LOCKDOWN_LIFT_BY_SYSRQ
bbfe8b3
 	  Allow the lockdown on a kernel to be lifted, by pressing a SysRq key
bbfe8b3
 	  combination on a wired keyboard.  On x86, this is SysRq+x.
bbfe8b3
bbfe8b3
+config LOCK_DOWN_IN_EFI_SECURE_BOOT
bbfe8b3
+	bool "Lock down the kernel in EFI Secure Boot mode"
bbfe8b3
+	default n
bbfe8b3
+	select LOCK_DOWN_KERNEL
bbfe8b3
+	depends on EFI
bbfe8b3
+	help
bbfe8b3
+	  UEFI Secure Boot provides a mechanism for ensuring that the firmware
bbfe8b3
+	  will only load signed bootloaders and kernels.  Secure boot mode may
bbfe8b3
+	  be determined from EFI variables provided by the system firmware if
bbfe8b3
+	  not indicated by the boot parameters.
bbfe8b3
+
bbfe8b3
+	  Enabling this option turns on results in kernel lockdown being
bbfe8b3
+	  triggered if EFI Secure Boot is set.
bbfe8b3
+
bbfe8b3
c97d3b0
 source "security/selinux/Kconfig"
c97d3b0
 source "security/smack/Kconfig"
bbfe8b3
diff --git a/security/lock_down.c b/security/lock_down.c
bbfe8b3
index 2c6b00f0c229..527f7e51dc8d 100644
bbfe8b3
--- a/security/lock_down.c
bbfe8b3
+++ b/security/lock_down.c
bbfe8b3
@@ -12,6 +12,7 @@
bbfe8b3
 #include <linux/export.h>
bbfe8b3
 #include <linux/sched.h>
bbfe8b3
 #include <linux/sysrq.h>
bbfe8b3
+#include <linux/efi.h>
bbfe8b3
 #include <asm/setup.h>
bbfe8b3
bbfe8b3
 #ifndef CONFIG_LOCK_DOWN_MANDATORY
bbfe8b3
@@ -55,6 +55,10 @@ void __init init_lockdown(void)
bbfe8b3
 #ifdef CONFIG_LOCK_DOWN_MANDATORY
bbfe8b3
 	pr_notice("Kernel is locked down from config; see man kernel_lockdown.7\n");
bbfe8b3
 #endif
bbfe8b3
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
bbfe8b3
+	if (efi_enabled(EFI_SECURE_BOOT))
bbfe8b3
+		lock_kernel_down("EFI secure boot");
bbfe8b3
+#endif
bbfe8b3
 }
bbfe8b3
bbfe8b3
 /**
bbfe8b3
-- 
bbfe8b3
2.14.3