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