Secure Boot updates

This commit is contained in:
Justin M. Forbes 2018-06-11 15:35:41 -05:00
parent 5a506e76b9
commit bbfe8b3016
3 changed files with 392 additions and 0 deletions

311
efi-secureboot.patch Normal file
View File

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

View File

@ -559,6 +559,9 @@ Patch210: disable-i8042-check-on-apple-mac.patch
Patch211: drm-i915-hush-check-crtc-state.patch Patch211: drm-i915-hush-check-crtc-state.patch
Patch212: efi-secureboot.patch
Patch213: lockdown-fix-coordination-of-kernel-module-signature-verification.patch
# 300 - ARM patches # 300 - ARM patches
Patch300: arm64-Add-option-of-13-for-FORCE_MAX_ZONEORDER.patch Patch300: arm64-Add-option-of-13-for-FORCE_MAX_ZONEORDER.patch
@ -1843,6 +1846,9 @@ fi
# #
# #
%changelog %changelog
* Mon Jun 11 2018 Justin M. Forbes <jforbes@fedoraproject.org>
- Secure Boot updates
* Mon Jun 11 2018 Laura Abbott <labbott@redhat.com> - 4.18.0-0.rc0.git6.1 * Mon Jun 11 2018 Laura Abbott <labbott@redhat.com> - 4.18.0-0.rc0.git6.1
- Linux v4.17-10288-ga2225d931f75 - Linux v4.17-10288-ga2225d931f75

View File

@ -0,0 +1,75 @@
From patchwork Fri Apr 13 15:27:52 2018
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: lockdown: fix coordination of kernel module signature verification
From: Mimi Zohar <zohar@linux.vnet.ibm.com>
X-Patchwork-Id: 10340277
Message-Id: <1523633272.3272.30.camel@linux.vnet.ibm.com>
To: David Howells <dhowells@redhat.com>
Cc: Luca Boccassi <bluca@debian.org>,
"Bruno E. O. Meneguele" <bmeneg@redhat.com>,
linux-integrity <linux-integrity@vger.kernel.org>,
linux-security-module <linux-security-module@vger.kernel.org>,
linux-kernel <linux-kernel@vger.kernel.org>
Date: Fri, 13 Apr 2018 11:27:52 -0400
If both IMA-appraisal and sig_enforce are enabled, then both signatures
are currently required. If the IMA-appraisal signature verification
fails, it could rely on the appended signature verification; but with the
lockdown patch set, the appended signature verification assumes that if
IMA-appraisal is enabled, it has verified the signature. Basically each
signature verification method would be relying on the other to verify the
kernel module signature.
This patch addresses the problem of requiring both kernel module signature
verification methods, when both are enabled, by verifying just the
appended signature.
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Acked-by: Bruno E. O. Meneguele <bmeneg@redhat.com>
---
kernel/module.c | 4 +---
security/integrity/ima/ima_main.c | 7 ++++++-
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/kernel/module.c b/kernel/module.c
index 9c1709a05037..60861eb7bc4d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -2803,9 +2803,7 @@ static int module_sig_check(struct load_info *info, int flags,
if (sig_enforce) {
pr_notice("%s is rejected\n", reason);
return -EKEYREJECTED;
- }
-
- if (can_do_ima_check && is_ima_appraise_enabled())
+ } else if (can_do_ima_check && is_ima_appraise_enabled())
return 0;
if (kernel_is_locked_down(reason))
return -EPERM;
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 754ece08e1c6..2155b1f316a4 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -480,6 +480,7 @@ static int read_idmap[READING_MAX_ID] = {
int ima_post_read_file(struct file *file, void *buf, loff_t size,
enum kernel_read_file_id read_id)
{
+ bool sig_enforce = is_module_sig_enforced();
enum ima_hooks func;
u32 secid;
@@ -490,7 +491,11 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
return 0;
}
- if (!file && read_id == READING_MODULE) /* MODULE_SIG_FORCE enabled */
+ /*
+ * If both IMA-appraisal and appended signature verification are
+ * enabled, rely on the appended signature verification.
+ */
+ if (sig_enforce && read_id == READING_MODULE)
return 0;
/* permit signed certs */