From 9299b76d51a58f80971bb75a358a1bd19a26da54 Mon Sep 17 00:00:00 2001
From: Kuntal Nayak <nkuntal@vmware.com>
Date: Sat, 23 Sep 2023 05:16:13 +0000
Subject: [PATCH 1/3] kernel: lockdown when UEFI secure boot enabled
Implemented a Kernel config that determines whether to lockdown
the kernel at boot time. During LSM initialization, UEFI Secure
Boot status is checked and kernel is locked down.
[AM: updated lockdown_lsm_init() logic to only go with secure boot
lockdown if force (unconditional) config options are not set.]
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
---
arch/x86/kernel/Makefile | 2 ++
arch/x86/kernel/lockdown.c | 21 +++++++++++++++++++++
include/linux/lockdown.h | 7 +++++++
security/lockdown/Kconfig | 8 ++++++++
security/lockdown/lockdown.c | 8 ++++++++
5 files changed, 46 insertions(+)
create mode 100644 arch/x86/kernel/lockdown.c
create mode 100644 include/linux/lockdown.h
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 42b5540da..4f9bbb047 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -144,6 +144,8 @@ obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev.o
obj-$(CONFIG_CFI_CLANG) += cfi.o
+obj-$(CONFIG_LOCK_DOWN_KERNEL_IN_SECUREBOOT) += lockdown.o
+
###
# 64 bit specific files
ifeq ($(CONFIG_X86_64),y)
diff --git a/arch/x86/kernel/lockdown.c b/arch/x86/kernel/lockdown.c
new file mode 100644
index 000000000..a94f910dc
--- /dev/null
+++ b/arch/x86/kernel/lockdown.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/efi.h>
+#include <linux/lockdown.h>
+
+#include <asm/efi.h>
+
+extern struct boot_params boot_params;
+
+/*
+ * Determine whether UEFI Secure Boot is enabled
+ */
+bool __init secureboot_enabled(void) {
+ if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
+ EFI64_LOADER_SIGNATURE, 4)) {
+ if (boot_params.secure_boot == efi_secureboot_mode_enabled)
+ return true;
+ }
+ return false;
+}
+
diff --git a/include/linux/lockdown.h b/include/linux/lockdown.h
new file mode 100644
index 000000000..04817eefd
--- /dev/null
+++ b/include/linux/lockdown.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_LOCKDOWN_H
+#define _LINUX_LOCKDOWN_H
+
+extern bool secureboot_enabled(void);
+
+#endif
diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig
index e84ddf484..f2fa07773 100644
--- a/security/lockdown/Kconfig
+++ b/security/lockdown/Kconfig
@@ -16,6 +16,14 @@ config SECURITY_LOCKDOWN_LSM_EARLY
subsystem is fully initialised. If enabled, lockdown will
unconditionally be called before any other LSMs.
+config LOCK_DOWN_KERNEL_IN_SECUREBOOT
+ bool "Enforce kernel lockdown when secure boot enabled"
+ depends on SECURITY_LOCKDOWN_LSM
+ default n
+ help
+ Option to enforce kernel lockdown in UEFI Secure Boot mode. Its
+ functioning depends on architecture specific implementation.
+
choice
prompt "Kernel default lockdown mode"
default LOCK_DOWN_KERNEL_FORCE_NONE
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index a79b985e9..8c36a94ad 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -13,6 +13,7 @@
#include <linux/security.h>
#include <linux/export.h>
#include <linux/lsm_hooks.h>
+#include <linux/lockdown.h>
static enum lockdown_reason kernel_locked_down;
@@ -20,6 +21,8 @@ static const enum lockdown_reason lockdown_levels[] = {LOCKDOWN_NONE,
LOCKDOWN_INTEGRITY_MAX,
LOCKDOWN_CONFIDENTIALITY_MAX};
+bool __init __weak secureboot_enabled(void) { return false; }
+
/*
* Put the kernel into lock-down mode.
*/
@@ -81,6 +84,11 @@ static int __init lockdown_lsm_init(void)
lock_kernel_down("Kernel configuration", LOCKDOWN_INTEGRITY_MAX);
#elif defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY)
lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX);
+#elif defined(CONFIG_LOCK_DOWN_KERNEL_IN_SECUREBOOT)
+ if (secureboot_enabled())
+ lock_kernel_down("Kernel configuration", LOCKDOWN_INTEGRITY_MAX);
+ else
+ pr_notice("Kernel not locked down\n");
#endif
security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks),
"lockdown");
--
2.39.0