Jeremy Cline e21e52b
From 478a0cff698409224330ea9e25eb332220b55dbb Mon Sep 17 00:00:00 2001
Jeremy Cline e21e52b
From: Jeremy Cline <jcline@redhat.com>
Jeremy Cline e21e52b
Date: Mon, 30 Sep 2019 21:22:47 +0000
Jeremy Cline e21e52b
Subject: [PATCH 1/3] security: lockdown: expose a hook to lock the kernel down
Jeremy Cline e21e52b
Jeremy Cline e21e52b
In order to automatically lock down kernels running on UEFI machines
Jeremy Cline e21e52b
booted in Secure Boot mode, expose the lock_kernel_down() hook.
Jeremy Cline e21e52b
Jeremy Cline e21e52b
Signed-off-by: Jeremy Cline <jcline@redhat.com>
Jeremy Cline e21e52b
---
Jeremy Cline e21e52b
 include/linux/lsm_hooks.h    | 8 ++++++++
Jeremy Cline e21e52b
 include/linux/security.h     | 5 +++++
Jeremy Cline e21e52b
 security/lockdown/lockdown.c | 1 +
Jeremy Cline e21e52b
 security/security.c          | 6 ++++++
Jeremy Cline e21e52b
 4 files changed, 20 insertions(+)
Jeremy Cline e21e52b
Jeremy Cline e21e52b
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
Jeremy Cline e21e52b
index a3763247547c..8d76d1f153ed 100644
Jeremy Cline e21e52b
--- a/include/linux/lsm_hooks.h
Jeremy Cline e21e52b
+++ b/include/linux/lsm_hooks.h
Jeremy Cline e21e52b
@@ -1454,6 +1454,12 @@
Jeremy Cline e21e52b
  *     code execution in kernel space should be permitted.
Jeremy Cline e21e52b
  *
Jeremy Cline e21e52b
  *     @what: kernel feature being accessed
Jeremy Cline e21e52b
+ *
Jeremy Cline e21e52b
+ * @lock_kernel_down
Jeremy Cline e21e52b
+ *     Put the kernel into lock-down mode.
Jeremy Cline e21e52b
+ *
Jeremy Cline e21e52b
+ *     @where: Where the lock-down is originating from (e.g. command line option)
Jeremy Cline e21e52b
+ *     @level: The lock-down level (can only increase)
Jeremy Cline e21e52b
  */
Jeremy Cline e21e52b
 union security_list_options {
Jeremy Cline e21e52b
 	int (*binder_set_context_mgr)(struct task_struct *mgr);
Jeremy Cline e21e52b
@@ -1818,6 +1824,7 @@ union security_list_options {
Jeremy Cline e21e52b
 	void (*bpf_prog_free_security)(struct bpf_prog_aux *aux);
Jeremy Cline e21e52b
 #endif /* CONFIG_BPF_SYSCALL */
Jeremy Cline e21e52b
 	int (*locked_down)(enum lockdown_reason what);
Jeremy Cline e21e52b
+	int (*lock_kernel_down)(const char *where, enum lockdown_reason level);
Jeremy Cline e21e52b
 };
Jeremy Cline e21e52b
 
Jeremy Cline e21e52b
 struct security_hook_heads {
Jeremy Cline e21e52b
@@ -2060,6 +2067,7 @@ struct security_hook_heads {
Jeremy Cline e21e52b
 	struct hlist_head bpf_prog_free_security;
Jeremy Cline e21e52b
 #endif /* CONFIG_BPF_SYSCALL */
Jeremy Cline e21e52b
 	struct hlist_head locked_down;
Jeremy Cline e21e52b
+	struct hlist_head lock_kernel_down;
Jeremy Cline e21e52b
 } __randomize_layout;
Jeremy Cline e21e52b
 
Jeremy Cline e21e52b
 /*
Jeremy Cline e21e52b
diff --git a/include/linux/security.h b/include/linux/security.h
Jeremy Cline e21e52b
index a8d59d612d27..467b9ccdf993 100644
Jeremy Cline e21e52b
--- a/include/linux/security.h
Jeremy Cline e21e52b
+++ b/include/linux/security.h
Jeremy Cline e21e52b
@@ -442,6 +442,7 @@ int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
Jeremy Cline e21e52b
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
Jeremy Cline e21e52b
 int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
Jeremy Cline e21e52b
 int security_locked_down(enum lockdown_reason what);
Jeremy Cline e21e52b
+int security_lock_kernel_down(const char *where, enum lockdown_reason level);
Jeremy Cline e21e52b
 #else /* CONFIG_SECURITY */
Jeremy Cline e21e52b
 
Jeremy Cline e21e52b
 static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data)
Jeremy Cline e21e52b
@@ -1269,6 +1270,10 @@ static inline int security_locked_down(enum lockdown_reason what)
Jeremy Cline e21e52b
 {
Jeremy Cline e21e52b
 	return 0;
Jeremy Cline e21e52b
 }
Jeremy Cline 391323a
+static inline int security_lock_kernel_down(const char *where, enum lockdown_reason level)
Jeremy Cline e21e52b
+{
Jeremy Cline e21e52b
+	return 0;
Jeremy Cline e21e52b
+}
Jeremy Cline e21e52b
 #endif	/* CONFIG_SECURITY */
Jeremy Cline e21e52b
 
Jeremy Cline e21e52b
 #ifdef CONFIG_SECURITY_NETWORK
Jeremy Cline e21e52b
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
Jeremy Cline e21e52b
index 8a10b43daf74..72a623075749 100644
Jeremy Cline e21e52b
--- a/security/lockdown/lockdown.c
Jeremy Cline e21e52b
+++ b/security/lockdown/lockdown.c
Jeremy Cline e21e52b
@@ -97,6 +97,7 @@ static int lockdown_is_locked_down(enum lockdown_reason what)
Jeremy Cline e21e52b
 
Jeremy Cline e21e52b
 static struct security_hook_list lockdown_hooks[] __lsm_ro_after_init = {
Jeremy Cline e21e52b
 	LSM_HOOK_INIT(locked_down, lockdown_is_locked_down),
Jeremy Cline e21e52b
+	LSM_HOOK_INIT(lock_kernel_down, lock_kernel_down),
Jeremy Cline e21e52b
 };
Jeremy Cline e21e52b
 
Jeremy Cline e21e52b
 static int __init lockdown_lsm_init(void)
Jeremy Cline e21e52b
diff --git a/security/security.c b/security/security.c
Jeremy Cline e21e52b
index 1bc000f834e2..1506b95427cf 100644
Jeremy Cline e21e52b
--- a/security/security.c
Jeremy Cline e21e52b
+++ b/security/security.c
Jeremy Cline e21e52b
@@ -2404,3 +2404,9 @@ int security_locked_down(enum lockdown_reason what)
Jeremy Cline e21e52b
 	return call_int_hook(locked_down, 0, what);
Jeremy Cline e21e52b
 }
Jeremy Cline e21e52b
 EXPORT_SYMBOL(security_locked_down);
Jeremy Cline e21e52b
+
Jeremy Cline e21e52b
+int security_lock_kernel_down(const char *where, enum lockdown_reason level)
Jeremy Cline e21e52b
+{
Jeremy Cline e21e52b
+	return call_int_hook(lock_kernel_down, 0, where, level);
Jeremy Cline e21e52b
+}
Jeremy Cline e21e52b
+EXPORT_SYMBOL(security_lock_kernel_down);
Jeremy Cline e21e52b
-- 
Jeremy Cline e21e52b
2.21.0
Jeremy Cline e21e52b
Jeremy Cline e21e52b
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
Jeremy Cline e21e52b
Subject: [PATCH 2/3] 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 0216117
[Rebased for context; efi_is_table_address was moved to arch/x86]
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 0216117
index bbe35bf879f5..7e528b6af86b 100644
bbfe8b3
--- a/arch/x86/kernel/setup.c
bbfe8b3
+++ b/arch/x86/kernel/setup.c
Jeremy Cline 0216117
@@ -1179,19 +1179,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 0216117
index 4ac2de4dfa72..195b078a423c 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 0216117
 obj-$(CONFIG_EFI_RCI2_TABLE)		+= rci2-table.o
Jeremy Cline c8f9da6
 
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 0216117
index 21d81021c1f4..758ec061d03b 100644
bbfe8b3
--- a/include/linux/efi.h
bbfe8b3
+++ b/include/linux/efi.h
Jeremy Cline 0216117
@@ -1204,6 +1204,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
 /*
Jeremy Cline 0216117
@@ -1214,6 +1222,8 @@ static inline bool efi_enabled(int feature)
Jeremy Cline 0216117
 	return test_bit(feature, &efi.flags) != 0;
Jeremy Cline 0216117
 }
16332ac
 extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
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
 {
Jeremy Cline 0216117
@@ -1227,6 +1237,8 @@ efi_capsule_pending(int *reset_type)
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 0216117
@@ -1619,12 +1631,6 @@ static inline bool efi_runtime_disabled(void) { return true; }
bbfe8b3
 extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
Jeremy Cline edfbff2
 extern unsigned long efi_call_virt_save_flags(void);
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 0216117
2.21.0
Jeremy Cline 0216117
bbfe8b3
Jeremy Cline e21e52b
From 15368f76d4997912318d35c52bfeb9041d85098e Mon Sep 17 00:00:00 2001
bbfe8b3
From: David Howells <dhowells@redhat.com>
Jeremy Cline e21e52b
Date: Mon, 30 Sep 2019 21:28:16 +0000
Jeremy Cline e21e52b
Subject: [PATCH 3/3] efi: Lock down the kernel if booted in secure boot mode
bbfe8b3
Jeremy Cline e21e52b
UEFI Secure Boot provides a mechanism for ensuring that the firmware
Jeremy Cline e21e52b
will only load signed bootloaders and kernels.  Certain use cases may
Jeremy Cline e21e52b
also require that all kernel modules also be signed.  Add a
Jeremy Cline e21e52b
configuration option that to lock down the kernel - which includes
Jeremy Cline e21e52b
requiring validly signed modules - if the kernel is secure-booted.
bbfe8b3
bbfe8b3
Signed-off-by: David Howells <dhowells@redhat.com>
Jeremy Cline e21e52b
Signed-off-by: Jeremy Cline <jcline@redhat.com>
bbfe8b3
---
Jeremy Cline e21e52b
 arch/x86/kernel/setup.c   |  8 ++++++++
Jeremy Cline e21e52b
 security/lockdown/Kconfig | 13 +++++++++++++
Jeremy Cline e21e52b
 2 files changed, 21 insertions(+)
bbfe8b3
bbfe8b3
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
Jeremy Cline e21e52b
index 77ea96b794bd..a119e1bc9623 100644
bbfe8b3
--- a/arch/x86/kernel/setup.c
bbfe8b3
+++ b/arch/x86/kernel/setup.c
Jeremy Cline e21e52b
@@ -73,6 +73,7 @@
Jeremy Cline e21e52b
 #include <linux/jiffies.h>
Jeremy Cline e21e52b
 #include <linux/mem_encrypt.h>
Jeremy Cline e21e52b
 #include <linux/sizes.h>
bbfe8b3
+#include <linux/security.h>
Jeremy Cline 4b5e423
 
Jeremy Cline e21e52b
 #include <linux/usb/xhci-dbgp.h>
Jeremy Cline e21e52b
 #include <video/edid.h>
Jeremy Cline e21e52b
@@ -1027,6 +1028,13 @@ void __init setup_arch(char **cmdline_p)
bbfe8b3
 	if (efi_enabled(EFI_BOOT))
bbfe8b3
 		efi_init();
Jeremy Cline 4b5e423
 
bbfe8b3
+	efi_set_secure_boot(boot_params.secure_boot);
bbfe8b3
+
Jeremy Cline e21e52b
+#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
Jeremy Cline e21e52b
+	if (efi_enabled(EFI_SECURE_BOOT))
Jeremy Cline e21e52b
+		security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_CONFIDENTIALITY_MAX);
Jeremy Cline e21e52b
+#endif
Jeremy Cline 4b5e423
+
2b2a5f0
 	dmi_setup();
2b2a5f0
 
2b2a5f0
 	/*
Jeremy Cline e21e52b
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
Jeremy Cline e21e52b
index e84ddf484010..d0501353a4b9 100644
Jeremy Cline e21e52b
--- a/security/lockdown/Kconfig
Jeremy Cline e21e52b
+++ b/security/lockdown/Kconfig
Jeremy Cline e21e52b
@@ -16,6 +16,19 @@ config SECURITY_LOCKDOWN_LSM_EARLY
Jeremy Cline e21e52b
 	  subsystem is fully initialised. If enabled, lockdown will
Jeremy Cline e21e52b
 	  unconditionally be called before any other LSMs.
Jeremy Cline 4b5e423
 
bbfe8b3
+config LOCK_DOWN_IN_EFI_SECURE_BOOT
bbfe8b3
+	bool "Lock down the kernel in EFI Secure Boot mode"
bbfe8b3
+	default n
Jeremy Cline e21e52b
+	depends on EFI && SECURITY_LOCKDOWN_LSM_EARLY
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
+
Jeremy Cline e21e52b
+	  Enabling this option results in kernel lockdown being triggered if
Jeremy Cline e21e52b
+	  EFI Secure Boot is set.
bbfe8b3
+
Jeremy Cline e21e52b
 choice
Jeremy Cline e21e52b
 	prompt "Kernel default lockdown mode"
Jeremy Cline e21e52b
 	default LOCK_DOWN_KERNEL_FORCE_NONE
bbfe8b3
-- 
Jeremy Cline e21e52b
2.21.0