From 4b5e4234be6539e237a2eaf36decf1b4b41fdc22 Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Apr 15 2019 16:15:16 +0000 Subject: Rebase the kernel lockdown patch set Use the latest version of the kernel lockdown patch set. This includes a few configuration renames: CONFIG_KEXEC_VERIFY_SIG became CONFIG_KEXEC_SIG and CONFIG_KEXEC_SIG_FORCE was added. CONFIG_KEXEC_SIG_FORCE=n because the "kexec_file: Restrict at runtime if the kernel is locked down" patch enforces the signature requirement when the kernel is locked down. CONFIG_LOCK_DOWN_MANDATORY got renamed to CONFIG_LOCK_DOWN_KERNEL_FORCE and remains false as LOCK_DOWN_IN_EFI_SECURE_BOOT covers enabling it for EFI Secure Boot users. Finally, the SysRq patches got dropped for the present. --- diff --git a/configs/fedora/generic/x86/CONFIG_KEXEC_SIG b/configs/fedora/generic/x86/CONFIG_KEXEC_SIG new file mode 100644 index 0000000..67b6886 --- /dev/null +++ b/configs/fedora/generic/x86/CONFIG_KEXEC_SIG @@ -0,0 +1 @@ +CONFIG_KEXEC_SIG=y diff --git a/configs/fedora/generic/x86/CONFIG_KEXEC_SIG_FORCE b/configs/fedora/generic/x86/CONFIG_KEXEC_SIG_FORCE new file mode 100644 index 0000000..21d707a --- /dev/null +++ b/configs/fedora/generic/x86/CONFIG_KEXEC_SIG_FORCE @@ -0,0 +1 @@ +# CONFIG_KEXEC_SIG_FORCE is not set diff --git a/configs/fedora/generic/x86/CONFIG_KEXEC_VERIFY_SIG b/configs/fedora/generic/x86/CONFIG_KEXEC_VERIFY_SIG deleted file mode 100644 index 5f39f19..0000000 --- a/configs/fedora/generic/x86/CONFIG_KEXEC_VERIFY_SIG +++ /dev/null @@ -1 +0,0 @@ -CONFIG_KEXEC_VERIFY_SIG=y diff --git a/configs/fedora/generic/x86/CONFIG_LOCK_DOWN_KERNEL_FORCE b/configs/fedora/generic/x86/CONFIG_LOCK_DOWN_KERNEL_FORCE new file mode 100644 index 0000000..b6a333e --- /dev/null +++ b/configs/fedora/generic/x86/CONFIG_LOCK_DOWN_KERNEL_FORCE @@ -0,0 +1 @@ +# CONFIG_LOCK_DOWN_KERNEL_FORCE is not set diff --git a/configs/fedora/generic/x86/CONFIG_LOCK_DOWN_MANDATORY b/configs/fedora/generic/x86/CONFIG_LOCK_DOWN_MANDATORY deleted file mode 100644 index 75d9b35..0000000 --- a/configs/fedora/generic/x86/CONFIG_LOCK_DOWN_MANDATORY +++ /dev/null @@ -1 +0,0 @@ -# CONFIG_LOCK_DOWN_MANDATORY is not set diff --git a/efi-lockdown.patch b/efi-lockdown.patch index 8bce057..b4a9ab5 100644 --- a/efi-lockdown.patch +++ b/efi-lockdown.patch @@ -1,81 +1,44 @@ -From e8b9c4420c929255708e0bff42142de49ff1971b Mon Sep 17 00:00:00 2001 +From 07ff2bbc3633a42ef5f0988b5bb821ed5d3399b9 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Mon, 9 Apr 2018 09:52:45 +0100 -Subject: [PATCH 01/22] Add the ability to lock down access to the running +Date: Mon, 18 Feb 2019 12:44:57 +0000 +Subject: [PATCH 01/27] Add the ability to lock down access to the running kernel image Provide a single call to allow kernel code to determine whether the system should be locked down, thereby disallowing various accesses that might -allow the running kernel image to be changed, including: - - - /dev/mem and similar - - Loading of unauthorised modules - - Fiddling with MSR registers - - Suspend to disk managed by the kernel - - Use of device DMA - -Two kernel configuration options are provided: - - (*) CONFIG_LOCK_DOWN_KERNEL - - This makes lockdown available and applies it to all the points that - need to be locked down if the mode is set. Lockdown mode can be - enabled by providing: - - lockdown=1 - - on the command line. - - (*) CONFIG_LOCK_DOWN_MANDATORY - - This forces lockdown on at compile time, overriding the command line - option. - -init_lockdown() is used as a hook from which lockdown can be managed in -future. It has to be called from arch setup code before things like ACPI -are enabled. - -Note that, with the other changes in this series, if lockdown mode is -enabled, the kernel will not be able to use certain drivers as the ability -to manually configure hardware parameters would then be prohibited. This -primarily applies to ISA hardware devices. +allow the running kernel image to be changed including the loading of +modules that aren't validly signed with a key we recognise, fiddling with +MSR registers and disallowing hibernation. Signed-off-by: David Howells +Acked-by: James Morris +Signed-off-by: Matthew Garrett --- - arch/x86/kernel/setup.c | 2 ++ - include/linux/kernel.h | 32 ++++++++++++++++++++ - security/Kconfig | 23 ++++++++++++++- - security/Makefile | 3 ++ - security/lock_down.c | 65 +++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 124 insertions(+), 1 deletion(-) + include/linux/kernel.h | 17 ++++++++++++ + include/linux/security.h | 9 +++++- + security/Kconfig | 15 ++++++++++ + security/Makefile | 3 ++ + security/lock_down.c | 60 ++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 security/lock_down.c -diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 3d872a527cd9..cf2f3df1b8d7 100644 ---- a/arch/x86/kernel/setup.c -+++ b/arch/x86/kernel/setup.c -@@ -1005,6 +1005,8 @@ void __init setup_arch(char **cmdline_p) - if (efi_enabled(EFI_BOOT)) - efi_init(); - -+ init_lockdown(); -+ - dmi_scan_machine(); - dmi_memdev_walk(); - dmi_set_dump_stack_arch_desc(); diff --git a/include/linux/kernel.h b/include/linux/kernel.h -index a8868a32098c..4e63db72cfea 100644 +index 8f0e68e250a7..833bf32ce4e6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h -@@ -350,6 +350,38 @@ static inline void refcount_error_report(struct pt_regs *regs, const char *err) +@@ -340,6 +340,23 @@ static inline void refcount_error_report(struct pt_regs *regs, const char *err) { } #endif +#ifdef CONFIG_LOCK_DOWN_KERNEL -+extern void __init init_lockdown(void); +extern bool __kernel_is_locked_down(const char *what, bool first); ++#else ++static inline bool __kernel_is_locked_down(const char *what, bool first) ++{ ++ return false; ++} ++#endif + -+#ifndef CONFIG_LOCK_DOWN_MANDATORY +#define kernel_is_locked_down(what) \ + ({ \ + static bool message_given; \ @@ -83,67 +46,54 @@ index a8868a32098c..4e63db72cfea 100644 + message_given = true; \ + locked_down; \ + }) -+#else -+#define kernel_is_locked_down(what) \ -+ ({ \ -+ static bool message_given; \ -+ __kernel_is_locked_down(what, !message_given); \ -+ message_given = true; \ -+ true; \ -+ }) -+#endif ++ + /* Internal, do not use. */ + int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res); + int __must_check _kstrtol(const char *s, unsigned int base, long *res); +diff --git a/include/linux/security.h b/include/linux/security.h +index 13537a49ae97..b290946341a4 100644 +--- a/include/linux/security.h ++++ b/include/linux/security.h +@@ -1798,5 +1798,12 @@ static inline void security_bpf_prog_free(struct bpf_prog_aux *aux) + #endif /* CONFIG_SECURITY */ + #endif /* CONFIG_BPF_SYSCALL */ + +-#endif /* ! __LINUX_SECURITY_H */ ++#ifdef CONFIG_LOCK_DOWN_KERNEL ++extern void __init init_lockdown(void); +#else +static inline void __init init_lockdown(void) +{ +} -+static inline bool __kernel_is_locked_down(const char *what, bool first) -+{ -+ return false; -+} -+#define kernel_is_locked_down(what) ({ false; }) +#endif -+ - /* Internal, do not use. */ - int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res); - int __must_check _kstrtol(const char *s, unsigned int base, long *res); + ++#endif /* ! __LINUX_SECURITY_H */ diff --git a/security/Kconfig b/security/Kconfig -index 1d6463fb1450..44c6a0da6f21 100644 +index 1d6463fb1450..47dc3403b5af 100644 --- a/security/Kconfig +++ b/security/Kconfig -@@ -229,6 +229,28 @@ config STATIC_USERMODEHELPER_PATH +@@ -229,6 +229,21 @@ config STATIC_USERMODEHELPER_PATH If you wish for all usermode helper programs to be disabled, specify an empty string here (i.e. ""). +config LOCK_DOWN_KERNEL + bool "Allow the kernel to be 'locked down'" + help -+ Allow the kernel to be locked down. Locking down the kernel turns -+ off various features that might otherwise allow access to the kernel -+ image (eg. setting MSR registers). ++ Allow the kernel to be locked down. If lockdown support is enabled ++ and activated, the kernel will impose additional restrictions ++ intended to prevent uid 0 from being able to modify the running ++ kernel. This may break userland applications that rely on low-level ++ access to hardware. + -+ Note, however, that locking down your kernel will prevent some -+ drivers from functioning because allowing manual configuration of -+ hardware parameters is forbidden, lest a device be used to access the -+ kernel by DMA. This mostly applies to ISA devices. -+ -+ The kernel lockdown can be triggered by adding lockdown=1 to the -+ kernel command line. -+ -+config LOCK_DOWN_MANDATORY -+ bool "Make kernel lockdown mandatory" -+ depends on LOCK_DOWN_KERNEL -+ help -+ Makes the lockdown non-negotiable. It is always on and cannot be -+ disabled. ++config LOCK_DOWN_KERNEL_FORCE ++ bool "Enable kernel lockdown mode automatically" ++ depends on LOCK_DOWN_KERNEL ++ help ++ Enable the kernel lock down functionality automatically at boot. + source "security/selinux/Kconfig" source "security/smack/Kconfig" source "security/tomoyo/Kconfig" -@@ -250,4 +272,3 @@ config LSM - If unsure, leave this as the default. - - endmenu -- diff --git a/security/Makefile b/security/Makefile index c598b904938f..5ff090149c88 100644 --- a/security/Makefile @@ -157,10 +107,11 @@ index c598b904938f..5ff090149c88 100644 +obj-$(CONFIG_LOCK_DOWN_KERNEL) += lock_down.o diff --git a/security/lock_down.c b/security/lock_down.c new file mode 100644 -index 000000000000..f35ffdd096ad +index 000000000000..18d8776a4d02 --- /dev/null +++ b/security/lock_down.c -@@ -0,0 +1,65 @@ +@@ -0,0 +1,60 @@ ++// SPDX-License-Identifier: GPL-2.0 +/* Lock down the kernel + * + * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. @@ -172,27 +123,21 @@ index 000000000000..f35ffdd096ad + * 2 of the Licence, or (at your option) any later version. + */ + ++#include +#include -+#include + -+#ifndef CONFIG_LOCK_DOWN_MANDATORY +static __ro_after_init bool kernel_locked_down; -+#else -+#define kernel_locked_down true -+#endif + +/* + * Put the kernel into lock-down mode. + */ +static void __init lock_kernel_down(const char *where) +{ -+#ifndef CONFIG_LOCK_DOWN_MANDATORY + if (!kernel_locked_down) { + kernel_locked_down = true; + pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", + where); + } -+#endif +} + +static int __init lockdown_param(char *ignored) @@ -209,8 +154,8 @@ index 000000000000..f35ffdd096ad + */ +void __init init_lockdown(void) +{ -+#ifdef CONFIG_LOCK_DOWN_MANDATORY -+ pr_notice("Kernel is locked down from config; see man kernel_lockdown.7\n"); ++#ifdef CONFIG_LOCK_DOWN_FORCE ++ lock_kernel_down("Kernel configuration"); +#endif +} + @@ -221,307 +166,121 @@ index 000000000000..f35ffdd096ad +bool __kernel_is_locked_down(const char *what, bool first) +{ + if (what && first && kernel_locked_down) -+ pr_notice("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n", -+ current->comm, what); ++ pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n", ++ what); + return kernel_locked_down; +} +EXPORT_SYMBOL(__kernel_is_locked_down); -- -2.20.1 +2.21.0 -From 2779f0447b80b3cf94fb0252a4b209aa36250ed6 Mon Sep 17 00:00:00 2001 -From: Kyle McMartin -Date: Mon, 9 Apr 2018 09:52:45 +0100 -Subject: [PATCH 02/22] Add a SysRq option to lift kernel lockdown +From e5709852ca1e9ed443d9abebcb35cbc2f0d9d987 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Mon, 18 Feb 2019 12:44:58 +0000 +Subject: [PATCH 02/27] Enforce module signatures if the kernel is locked down -Make an option to provide a sysrq key that will lift the kernel lockdown, -thereby allowing the running kernel image to be accessed and modified. +If the kernel is locked down, require that all modules have valid +signatures that we can verify. -On x86 this is triggered with SysRq+x, but this key may not be available on -all arches, so it is set by setting LOCKDOWN_LIFT_KEY in asm/setup.h. -Since this macro must be defined in an arch to be able to use this facility -for that arch, the Kconfig option is restricted to arches that support it. +I have adjusted the errors generated: + + (1) If there's no signature (ENODATA) or we can't check it (ENOPKG, + ENOKEY), then: + + (a) If signatures are enforced then EKEYREJECTED is returned. + + (b) If there's no signature or we can't check it, but the kernel is + locked down then EPERM is returned (this is then consistent with + other lockdown cases). + + (2) If the signature is unparseable (EBADMSG, EINVAL), the signature fails + the check (EKEYREJECTED) or a system error occurs (eg. ENOMEM), we + return the error we got. + +Note that the X.509 code doesn't check for key expiry as the RTC might not +be valid or might not have been transferred to the kernel's clock yet. + + [Modified by Matthew Garrett to remove the IMA integration. This will + be replaced with integration with the IMA architecture policy + patchset.] -Signed-off-by: Kyle McMartin Signed-off-by: David Howells -cc: x86@kernel.org +Reviewed-by: Jiri Bohac +Signed-off-by: Matthew Garrett +Cc: Jessica Yu --- - arch/x86/include/asm/setup.h | 2 ++ - drivers/input/misc/uinput.c | 1 + - drivers/tty/sysrq.c | 19 ++++++++++----- - include/linux/input.h | 5 ++++ - include/linux/sysrq.h | 8 +++++- - kernel/debug/kdb/kdb_main.c | 2 +- - security/Kconfig | 11 +++++++++ - security/lock_down.c | 47 ++++++++++++++++++++++++++++++++++++ - 8 files changed, 87 insertions(+), 8 deletions(-) - -diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h -index ed8ec011a9fd..8daf633a5347 100644 ---- a/arch/x86/include/asm/setup.h -+++ b/arch/x86/include/asm/setup.h -@@ -9,6 +9,8 @@ - #include - #include - -+#define LOCKDOWN_LIFT_KEY 'x' -+ - #ifdef __i386__ - - #include -diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c -index 26ec603fe220..a73e92490286 100644 ---- a/drivers/input/misc/uinput.c -+++ b/drivers/input/misc/uinput.c -@@ -366,6 +366,7 @@ static int uinput_create_device(struct uinput_device *udev) - dev->flush = uinput_dev_flush; - } - -+ dev->flags |= INPUTDEV_FLAGS_SYNTHETIC; - dev->event = uinput_dev_event; - - input_set_drvdata(udev->dev, udev); -diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c -index fa0ce7dd9e24..06c60fed7656 100644 ---- a/drivers/tty/sysrq.c -+++ b/drivers/tty/sysrq.c -@@ -480,6 +480,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { - /* x: May be registered on mips for TLB dump */ - /* x: May be registered on ppc/powerpc for xmon */ - /* x: May be registered on sparc64 for global PMU dump */ -+ /* x: May be registered on x86_64 for disabling secure boot */ - NULL, /* x */ - /* y: May be registered on sparc64 for global register dump */ - NULL, /* y */ -@@ -523,7 +524,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) - sysrq_key_table[i] = op_p; - } - --void __handle_sysrq(int key, bool check_mask) -+void __handle_sysrq(int key, unsigned int from) + kernel/module.c | 39 ++++++++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 7 deletions(-) + +diff --git a/kernel/module.c b/kernel/module.c +index 2ad1b5239910..9a377c6ea200 100644 +--- a/kernel/module.c ++++ b/kernel/module.c +@@ -2767,8 +2767,9 @@ static inline void kmemleak_load_module(const struct module *mod, + #ifdef CONFIG_MODULE_SIG + static int module_sig_check(struct load_info *info, int flags) { - struct sysrq_key_op *op_p; - int orig_log_level; -@@ -542,11 +543,15 @@ void __handle_sysrq(int key, bool check_mask) - - op_p = __sysrq_get_key_op(key); - if (op_p) { -+ /* Ban synthetic events from some sysrq functionality */ -+ if ((from == SYSRQ_FROM_PROC || from == SYSRQ_FROM_SYNTHETIC) && -+ op_p->enable_mask & SYSRQ_DISABLE_USERSPACE) -+ printk("This sysrq operation is disabled from userspace.\n"); - /* - * Should we check for enabled operations (/proc/sysrq-trigger - * should not) and is the invoked operation enabled? - */ -- if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { -+ if (from == SYSRQ_FROM_KERNEL || sysrq_on_mask(op_p->enable_mask)) { - pr_info("%s\n", op_p->action_msg); - console_loglevel = orig_log_level; - op_p->handler(key); -@@ -579,7 +584,7 @@ void __handle_sysrq(int key, bool check_mask) - void handle_sysrq(int key) - { - if (sysrq_on()) -- __handle_sysrq(key, true); -+ __handle_sysrq(key, SYSRQ_FROM_KERNEL); - } - EXPORT_SYMBOL(handle_sysrq); +- int err = -ENOKEY; ++ int err = -ENODATA; + const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; ++ const char *reason; + const void *mod = info->hdr; -@@ -659,7 +664,7 @@ static void sysrq_do_reset(struct timer_list *t) - static void sysrq_handle_reset_request(struct sysrq_state *state) - { - if (state->reset_requested) -- __handle_sysrq(sysrq_xlate[KEY_B], false); -+ __handle_sysrq(sysrq_xlate[KEY_B], SYSRQ_FROM_KERNEL); - - if (sysrq_reset_downtime_ms) - mod_timer(&state->keyreset_timer, -@@ -812,8 +817,10 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, - - default: - if (sysrq->active && value && value != 2) { -+ int from = sysrq->handle.dev->flags & INPUTDEV_FLAGS_SYNTHETIC ? -+ SYSRQ_FROM_SYNTHETIC : 0; - sysrq->need_reinject = false; -- __handle_sysrq(sysrq_xlate[code], true); -+ __handle_sysrq(sysrq_xlate[code], from); - } - break; - } -@@ -1096,7 +1103,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, - - if (get_user(c, buf)) - return -EFAULT; -- __handle_sysrq(c, false); -+ __handle_sysrq(c, SYSRQ_FROM_PROC); + /* +@@ -2783,16 +2784,40 @@ static int module_sig_check(struct load_info *info, int flags) + err = mod_verify_sig(mod, info); } - return count; -diff --git a/include/linux/input.h b/include/linux/input.h -index 7c7516eb7d76..38cd0ea72c37 100644 ---- a/include/linux/input.h -+++ b/include/linux/input.h -@@ -42,6 +42,7 @@ struct input_value { - * @phys: physical path to the device in the system hierarchy - * @uniq: unique identification code for the device (if device has it) - * @id: id of the device (struct input_id) -+ * @flags: input device flags (SYNTHETIC, etc.) - * @propbit: bitmap of device properties and quirks - * @evbit: bitmap of types of events supported by the device (EV_KEY, - * EV_REL, etc.) -@@ -124,6 +125,8 @@ struct input_dev { - const char *uniq; - struct input_id id; - -+ unsigned int flags; -+ - unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)]; - - unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; -@@ -190,6 +193,8 @@ struct input_dev { - }; - #define to_input_dev(d) container_of(d, struct input_dev, dev) - -+#define INPUTDEV_FLAGS_SYNTHETIC 0x000000001 -+ - /* - * Verify that we are in sync with input_device_id mod_devicetable.h #defines - */ -diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h -index 8c71874e8485..7de1f08b60a9 100644 ---- a/include/linux/sysrq.h -+++ b/include/linux/sysrq.h -@@ -29,6 +29,8 @@ - #define SYSRQ_ENABLE_BOOT 0x0080 - #define SYSRQ_ENABLE_RTNICE 0x0100 - -+#define SYSRQ_DISABLE_USERSPACE 0x00010000 -+ - struct sysrq_key_op { - void (*handler)(int); - char *help_msg; -@@ -43,8 +45,12 @@ struct sysrq_key_op { - * are available -- else NULL's). - */ - -+#define SYSRQ_FROM_KERNEL 0x0001 -+#define SYSRQ_FROM_PROC 0x0002 -+#define SYSRQ_FROM_SYNTHETIC 0x0004 -+ - void handle_sysrq(int key); --void __handle_sysrq(int key, bool check_mask); -+void __handle_sysrq(int key, unsigned int from); - int register_sysrq_key(int key, struct sysrq_key_op *op); - int unregister_sysrq_key(int key, struct sysrq_key_op *op); - struct sysrq_key_op *__sysrq_get_key_op(int key); -diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c -index 82a3b32a7cfc..efee1abf5e8e 100644 ---- a/kernel/debug/kdb/kdb_main.c -+++ b/kernel/debug/kdb/kdb_main.c -@@ -1981,7 +1981,7 @@ static int kdb_sr(int argc, const char **argv) - return KDB_ARGCOUNT; - - kdb_trap_printk++; -- __handle_sysrq(*argv[1], check_mask); -+ __handle_sysrq(*argv[1], check_mask ? SYSRQ_FROM_KERNEL : 0); - kdb_trap_printk--; - - return 0; -diff --git a/security/Kconfig b/security/Kconfig -index 44c6a0da6f21..f885e88e0705 100644 ---- a/security/Kconfig -+++ b/security/Kconfig -@@ -251,6 +251,17 @@ config LOCK_DOWN_MANDATORY - Makes the lockdown non-negotiable. It is always on and cannot be - disabled. - -+config ALLOW_LOCKDOWN_LIFT_BY_SYSRQ -+ bool "Allow the kernel lockdown to be lifted by SysRq" -+ depends on LOCK_DOWN_KERNEL -+ depends on !LOCK_DOWN_MANDATORY -+ depends on MAGIC_SYSRQ -+ depends on X86 -+ help -+ 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. -+ -+ - source "security/selinux/Kconfig" - source "security/smack/Kconfig" - source "security/tomoyo/Kconfig" -diff --git a/security/lock_down.c b/security/lock_down.c -index f35ffdd096ad..2615669dbf03 100644 ---- a/security/lock_down.c -+++ b/security/lock_down.c -@@ -11,9 +11,15 @@ - - #include - #include -+#include -+#include +- if (!err) { ++ switch (err) { ++ case 0: + info->sig_ok = true; + return 0; +- } + +- /* Not having a signature is only an error if we're strict. */ +- if (err == -ENOKEY && !is_module_sig_enforced()) +- err = 0; ++ /* We don't permit modules to be loaded into trusted kernels ++ * without a valid signature on them, but if we're not ++ * enforcing, certain errors are non-fatal. ++ */ ++ case -ENODATA: ++ reason = "Loading of unsigned module"; ++ goto decide; ++ case -ENOPKG: ++ reason = "Loading of module with unsupported crypto"; ++ goto decide; ++ case -ENOKEY: ++ reason = "Loading of module with unavailable key"; ++ decide: ++ if (is_module_sig_enforced()) { ++ pr_notice("%s is rejected\n", reason); ++ return -EKEYREJECTED; ++ } - #ifndef CONFIG_LOCK_DOWN_MANDATORY -+#ifdef CONFIG_ALLOW_LOCKDOWN_LIFT_BY_SYSRQ -+static __read_mostly bool kernel_locked_down; -+#else - static __ro_after_init bool kernel_locked_down; -+#endif - #else - #define kernel_locked_down true - #endif -@@ -63,3 +69,44 @@ bool __kernel_is_locked_down(const char *what, bool first) - return kernel_locked_down; - } - EXPORT_SYMBOL(__kernel_is_locked_down); -+ -+#ifdef CONFIG_ALLOW_LOCKDOWN_LIFT_BY_SYSRQ -+ -+/* -+ * Take the kernel out of lockdown mode. -+ */ -+static void lift_kernel_lockdown(void) -+{ -+ pr_notice("Lifting lockdown\n"); -+ kernel_locked_down = false; -+} +- return err; ++ if (kernel_is_locked_down(reason)) ++ return -EPERM; ++ return 0; + -+/* -+ * Allow lockdown to be lifted by pressing something like SysRq+x (and not by -+ * echoing the appropriate letter into the sysrq-trigger file). -+ */ -+static void sysrq_handle_lockdown_lift(int key) -+{ -+ if (kernel_locked_down) -+ lift_kernel_lockdown(); -+} -+ -+static struct sysrq_key_op lockdown_lift_sysrq_op = { -+ .handler = sysrq_handle_lockdown_lift, -+ .help_msg = "unSB(x)", -+ .action_msg = "Disabling Secure Boot restrictions", -+ .enable_mask = SYSRQ_DISABLE_USERSPACE, -+}; -+ -+static int __init lockdown_lift_sysrq(void) -+{ -+ if (kernel_locked_down) { -+ lockdown_lift_sysrq_op.help_msg[5] = LOCKDOWN_LIFT_KEY; -+ register_sysrq_key(LOCKDOWN_LIFT_KEY, &lockdown_lift_sysrq_op); ++ /* All other errors are fatal, including nomem, unparseable ++ * signatures and signature check failures - even if signatures ++ * aren't required. ++ */ ++ default: ++ return err; + } -+ return 0; -+} -+ -+late_initcall(lockdown_lift_sysrq); -+ -+#endif /* CONFIG_ALLOW_LOCKDOWN_LIFT_BY_SYSRQ */ + } + #else /* !CONFIG_MODULE_SIG */ + static int module_sig_check(struct load_info *info, int flags) -- -2.20.1 +2.21.0 -From 597069f3ba9dbf3537bd2ab5642f203fa24fd1f4 Mon Sep 17 00:00:00 2001 +From 4da16916fdf7dd6271bc6f16c0f9c32f430e7b42 Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: Mon, 9 Apr 2018 09:52:46 +0100 -Subject: [PATCH 03/22] Restrict /dev/{mem,kmem,port} when the kernel is locked +Date: Mon, 18 Feb 2019 12:44:58 +0000 +Subject: [PATCH 03/27] Restrict /dev/{mem,kmem,port} when the kernel is locked down Allowing users to read and write to core kernel memory makes it possible @@ -536,7 +295,8 @@ thus DMA from being used to accomplish the same thing. Signed-off-by: Matthew Garrett Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" +Signed-off-by: Matthew Garrett +Cc: x86@kernel.org --- drivers/char/mem.c | 2 ++ 1 file changed, 2 insertions(+) @@ -555,12 +315,12 @@ index b08dc50f9f26..0a2f2e75d5f4 100644 } -- -2.20.1 +2.21.0 -From 97b73030d3ccb2c4595c4fe948b0af368a6b10e3 Mon Sep 17 00:00:00 2001 +From e6802bece8b23dea57d5dfe72dc8383d0fa7f89c Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: Mon, 9 Apr 2018 09:52:46 +0100 -Subject: [PATCH 04/22] kexec_load: Disable at runtime if the kernel is locked +Date: Mon, 18 Feb 2019 12:44:58 +0000 +Subject: [PATCH 04/27] kexec_load: Disable at runtime if the kernel is locked down The kexec_load() syscall permits the loading and execution of arbitrary @@ -573,21 +333,19 @@ signature on the image to be booted. Signed-off-by: Matthew Garrett Signed-off-by: David Howells Acked-by: Dave Young -Reviewed-by: "Lee, Chun-Yi" -Reviewed-by: James Morris cc: kexec@lists.infradead.org -Signed-off-by: Jeremy Cline +Signed-off-by: Matthew Garrett --- kernel/kexec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/kexec.c b/kernel/kexec.c -index 68559808fdfa..041d505070e1 100644 +index 68559808fdfa..8ea0ce31271f 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c -@@ -202,6 +202,13 @@ static inline int kexec_load_check(unsigned long nr_segments, - if (!capable(CAP_SYS_BOOT) || kexec_load_disabled) - return -EPERM; +@@ -207,6 +207,13 @@ static inline int kexec_load_check(unsigned long nr_segments, + if (result < 0) + return result; + /* + * kexec can be used to circumvent module loading restrictions, so @@ -596,16 +354,313 @@ index 68559808fdfa..041d505070e1 100644 + if (kernel_is_locked_down("kexec of unsigned images")) + return -EPERM; + - /* Permit LSMs and IMA to fail the kexec */ - result = security_kernel_load_data(LOADING_KEXEC_IMAGE); - if (result < 0) + /* + * Verify we have a legal set of flags + * This leaves us room for future extensions. +-- +2.21.0 + +From 082fd91e5e574dff4063bc6062378ae581747c5a Mon Sep 17 00:00:00 2001 +From: Dave Young +Date: Mon, 18 Feb 2019 12:44:58 +0000 +Subject: [PATCH 05/27] 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 +Signed-off-by: David Howells +cc: kexec@lists.infradead.org +Signed-off-by: Matthew Garrett +--- + 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 278cd07228dd..d49554b948fd 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.20.1 +2.21.0 + +From 4b84eb5e3c362deee572d47d12e8dd30d6ad1333 Mon Sep 17 00:00:00 2001 +From: Jiri Bohac +Date: Mon, 18 Feb 2019 12:44:58 +0000 +Subject: [PATCH 06/27] kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and + KEXEC_SIG_FORCE + +This is a preparatory patch for kexec_file_load() lockdown. A locked down +kernel needs to prevent unsigned kernel images from being loaded with +kexec_file_load(). Currently, the only way to force the signature +verification is compiling with KEXEC_VERIFY_SIG. This prevents loading +usigned images even when the kernel is not locked down at runtime. + +This patch splits KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE. +Analogous to the MODULE_SIG and MODULE_SIG_FORCE for modules, KEXEC_SIG +turns on the signature verification but allows unsigned images to be +loaded. KEXEC_SIG_FORCE disallows images without a valid signature. + +[Modified by David Howells such that: -From 1b27ccaab50813a5a3c29f7be294a3cf98966d3b Mon Sep 17 00:00:00 2001 + (1) verify_pefile_signature() differentiates between no-signature and + sig-didn't-match in its returned errors. + + (2) kexec fails with EKEYREJECTED and logs an appropriate message if + signature checking is enforced and an signature is not found, uses + unsupported crypto or has no matching key. + + (3) kexec fails with EKEYREJECTED if there is a signature for which we + have a key, but signature doesn't match - even if in non-forcing mode. + + (4) kexec fails with EBADMSG or some other error if there is a signature + which cannot be parsed - even if in non-forcing mode. + + (5) kexec fails with ELIBBAD if the PE file cannot be parsed to extract + the signature - even if in non-forcing mode. + +] + +Signed-off-by: Jiri Bohac +Signed-off-by: David Howells +Reviewed-by: Jiri Bohac +cc: kexec@lists.infradead.org +Signed-off-by: Matthew Garrett +--- + arch/x86/Kconfig | 20 ++++++++--- + crypto/asymmetric_keys/verify_pefile.c | 4 ++- + include/linux/kexec.h | 4 +-- + kernel/kexec_file.c | 48 ++++++++++++++++++++++---- + 4 files changed, 61 insertions(+), 15 deletions(-) + +diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig +index 4b4a7f32b68e..735d04a4b18f 100644 +--- a/arch/x86/Kconfig ++++ b/arch/x86/Kconfig +@@ -2016,20 +2016,30 @@ config KEXEC_FILE + config ARCH_HAS_KEXEC_PURGATORY + def_bool KEXEC_FILE + +-config KEXEC_VERIFY_SIG ++config KEXEC_SIG + bool "Verify kernel signature during kexec_file_load() syscall" + depends on KEXEC_FILE + ---help--- +- This option makes kernel signature verification mandatory for +- the kexec_file_load() syscall. + +- In addition to that option, you need to enable signature ++ This option makes the kexec_file_load() syscall check for a valid ++ signature of the kernel image. The image can still be loaded without ++ a valid signature unless you also enable KEXEC_SIG_FORCE, though if ++ there's a signature that we can check, then it must be valid. ++ ++ In addition to this option, you need to enable signature + verification for the corresponding kernel image type being + loaded in order for this to work. + ++config KEXEC_SIG_FORCE ++ bool "Require a valid signature in kexec_file_load() syscall" ++ depends on KEXEC_SIG ++ ---help--- ++ This option makes kernel signature verification mandatory for ++ the kexec_file_load() syscall. ++ + config KEXEC_BZIMAGE_VERIFY_SIG + bool "Enable bzImage signature verification support" +- depends on KEXEC_VERIFY_SIG ++ depends on KEXEC_SIG + depends on SIGNED_PE_FILE_VERIFICATION + select SYSTEM_TRUSTED_KEYRING + ---help--- +diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c +index d178650fd524..4473cea1e877 100644 +--- a/crypto/asymmetric_keys/verify_pefile.c ++++ b/crypto/asymmetric_keys/verify_pefile.c +@@ -100,7 +100,7 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen, + + if (!ddir->certs.virtual_address || !ddir->certs.size) { + pr_debug("Unsigned PE binary\n"); +- return -EKEYREJECTED; ++ return -ENODATA; + } + + chkaddr(ctx->header_size, ddir->certs.virtual_address, +@@ -408,6 +408,8 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen, + * (*) 0 if at least one signature chain intersects with the keys in the trust + * keyring, or: + * ++ * (*) -ENODATA if there is no signature present. ++ * + * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a + * chain. + * +diff --git a/include/linux/kexec.h b/include/linux/kexec.h +index b9b1bc5f9669..58b27c7bdc2b 100644 +--- a/include/linux/kexec.h ++++ b/include/linux/kexec.h +@@ -125,7 +125,7 @@ typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf, + unsigned long cmdline_len); + typedef int (kexec_cleanup_t)(void *loader_data); + +-#ifdef CONFIG_KEXEC_VERIFY_SIG ++#ifdef CONFIG_KEXEC_SIG + typedef int (kexec_verify_sig_t)(const char *kernel_buf, + unsigned long kernel_len); + #endif +@@ -134,7 +134,7 @@ struct kexec_file_ops { + kexec_probe_t *probe; + kexec_load_t *load; + kexec_cleanup_t *cleanup; +-#ifdef CONFIG_KEXEC_VERIFY_SIG ++#ifdef CONFIG_KEXEC_SIG + kexec_verify_sig_t *verify_sig; + #endif + }; +diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c +index f1d0e00a3971..67f3a866eabe 100644 +--- a/kernel/kexec_file.c ++++ b/kernel/kexec_file.c +@@ -90,7 +90,7 @@ int __weak arch_kimage_file_post_load_cleanup(struct kimage *image) + return kexec_image_post_load_cleanup_default(image); + } + +-#ifdef CONFIG_KEXEC_VERIFY_SIG ++#ifdef CONFIG_KEXEC_SIG + static int kexec_image_verify_sig_default(struct kimage *image, void *buf, + unsigned long buf_len) + { +@@ -188,7 +188,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, + const char __user *cmdline_ptr, + unsigned long cmdline_len, unsigned flags) + { +- int ret = 0; ++ const char *reason; ++ int ret; + void *ldata; + loff_t size; + +@@ -207,15 +208,48 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, + if (ret) + goto out; + +-#ifdef CONFIG_KEXEC_VERIFY_SIG ++#ifdef CONFIG_KEXEC_SIG + ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf, + image->kernel_buf_len); +- if (ret) { +- pr_debug("kernel signature verification failed.\n"); ++#else ++ ret = -ENODATA; ++#endif ++ ++ switch (ret) { ++ case 0: ++ break; ++ ++ /* Certain verification errors are non-fatal if we're not ++ * checking errors, provided we aren't mandating that there ++ * must be a valid signature. ++ */ ++ case -ENODATA: ++ reason = "kexec of unsigned image"; ++ goto decide; ++ case -ENOPKG: ++ reason = "kexec of image with unsupported crypto"; ++ goto decide; ++ case -ENOKEY: ++ reason = "kexec of image with unavailable key"; ++ decide: ++ if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) { ++ pr_notice("%s rejected\n", reason); ++ ret = -EKEYREJECTED; ++ goto out; ++ } ++ ++ ret = 0; ++ break; ++ ++ /* All other errors are fatal, including nomem, unparseable ++ * signatures and signature check failures - even if signatures ++ * aren't required. ++ */ ++ default: ++ pr_notice("kernel signature verification failed (%d).\n", ret); + goto out; + } +- pr_debug("kernel signature verification successful.\n"); +-#endif ++ + /* It is possible that there no initramfs is being loaded */ + if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { + ret = kernel_read_file_from_fd(initrd_fd, &image->initrd_buf, +-- +2.21.0 + +From 854a15bda329f93a425d592cd10d06c3a0486e75 Mon Sep 17 00:00:00 2001 +From: Jiri Bohac +Date: Mon, 18 Feb 2019 12:44:58 +0000 +Subject: [PATCH 07/27] kexec_file: Restrict at runtime if the kernel is locked + down + +When KEXEC_SIG is not enabled, kernel should not load images through +kexec_file systemcall if the kernel is locked down. + +[Modified by David Howells to fit with modifications to the previous patch + and to return -EPERM if the kernel is locked down for consistency with + other lockdowns. Modified by Matthew Garrett to remove the IMA + integration, which will be replaced by integrating with the IMA + architecture policy patches.] + +Signed-off-by: Jiri Bohac +Signed-off-by: David Howells +Reviewed-by: Jiri Bohac +cc: kexec@lists.infradead.org +Signed-off-by: Matthew Garrett +--- + kernel/kexec_file.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c +index 67f3a866eabe..0cfe4f6f7f85 100644 +--- a/kernel/kexec_file.c ++++ b/kernel/kexec_file.c +@@ -239,6 +239,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, + } + + ret = 0; ++ ++ if (kernel_is_locked_down(reason)) { ++ ret = -EPERM; ++ goto out; ++ } ++ + break; + + /* All other errors are fatal, including nomem, unparseable +-- +2.21.0 + +From 5077fcf70e31cb618274da06a8ef3b49aa92cda0 Mon Sep 17 00:00:00 2001 From: Josh Boyer -Date: Mon, 9 Apr 2018 09:52:47 +0100 -Subject: [PATCH 05/22] hibernate: Disable when the kernel is locked down +Date: Mon, 18 Feb 2019 12:44:59 +0000 +Subject: [PATCH 08/27] hibernate: Disable when the kernel is locked down There is currently no way to verify the resume image when returning from hibernate. This might compromise the signed modules trust model, @@ -614,9 +669,10 @@ kernel is locked down. Signed-off-by: Josh Boyer Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" +Cc: rjw@rjwysocki.net +Cc: pavel@ucw.cz cc: linux-pm@vger.kernel.org -Signed-off-by: Jeremy Cline +Signed-off-by: Matthew Garrett --- kernel/power/hibernate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) @@ -635,12 +691,12 @@ index abef759de7c8..802795becb88 100644 /** -- -2.20.1 +2.21.0 -From 65c098838ab0e21528ecbd5ad27e1b5174b42b14 Mon Sep 17 00:00:00 2001 +From 6687ec57697209008a846f94b8079dd3b8c5426d Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: Mon, 9 Apr 2018 09:52:47 +0100 -Subject: [PATCH 06/22] uswsusp: Disable when the kernel is locked down +Date: Mon, 18 Feb 2019 12:44:59 +0000 +Subject: [PATCH 09/27] uswsusp: Disable when the kernel is locked down uswsusp allows a user process to dump and then restore kernel state, which makes it possible to modify the running kernel. Disable this if the kernel @@ -648,9 +704,11 @@ is locked down. Signed-off-by: Matthew Garrett Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" Reviewed-by: James Morris cc: linux-pm@vger.kernel.org +Cc: pavel@ucw.cz +Cc: rjw@rjwysocki.net +Signed-off-by: Matthew Garrett --- kernel/power/user.c | 3 +++ 1 file changed, 3 insertions(+) @@ -670,12 +728,12 @@ index 2d8b60a3c86b..0305d513c274 100644 if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { -- -2.20.1 +2.21.0 -From 05eecdf72d557817d7613733dca6eac08e61377e Mon Sep 17 00:00:00 2001 +From 074f89fba44418ebcf18e0ebbf1ed63fbc0b1d49 Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: Mon, 9 Apr 2018 09:52:48 +0100 -Subject: [PATCH 07/22] PCI: Lock down BAR access when the kernel is locked +Date: Mon, 18 Feb 2019 12:44:59 +0000 +Subject: [PATCH 10/27] PCI: Lock down BAR access when the kernel is locked down Any hardware that can potentially generate DMA has to be locked down in @@ -687,8 +745,8 @@ sufficiently IOMMU-isolated devices. Signed-off-by: Matthew Garrett Signed-off-by: David Howells Acked-by: Bjorn Helgaas -Reviewed-by: "Lee, Chun-Yi" cc: linux-pci@vger.kernel.org +Signed-off-by: Matthew Garrett --- drivers/pci/pci-sysfs.c | 9 +++++++++ drivers/pci/proc.c | 9 ++++++++- @@ -696,10 +754,10 @@ cc: linux-pci@vger.kernel.org 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c -index 25794c27c7a4..0d969598e273 100644 +index 9ecfe13157c0..40c14574fcf8 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c -@@ -904,6 +904,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj, +@@ -905,6 +905,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj, loff_t init_off = off; u8 *data = (u8 *) buf; @@ -709,7 +767,7 @@ index 25794c27c7a4..0d969598e273 100644 if (off > dev->cfg_size) return 0; if (off + count > dev->cfg_size) { -@@ -1166,6 +1169,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, +@@ -1167,6 +1170,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, enum pci_mmap_state mmap_type; struct resource *res = &pdev->resource[bar]; @@ -719,7 +777,7 @@ index 25794c27c7a4..0d969598e273 100644 if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start)) return -EINVAL; -@@ -1241,6 +1247,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj, +@@ -1242,6 +1248,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { @@ -778,12 +836,12 @@ index d96626c614f5..b8a08d3166a1 100644 dev = pci_get_domain_bus_and_slot(0, bus, dfn); -- -2.20.1 +2.21.0 -From 00ead3a144b821267a941a26c646a1fd07d8163a Mon Sep 17 00:00:00 2001 +From 206cc8259d1da899524e42e506c5ea975a28082a Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: Mon, 9 Apr 2018 09:52:48 +0100 -Subject: [PATCH 08/22] x86: Lock down IO port access when the kernel is locked +Date: Mon, 18 Feb 2019 12:44:59 +0000 +Subject: [PATCH 11/27] x86: Lock down IO port access when the kernel is locked down IO port access would permit users to gain access to PCI configuration @@ -797,8 +855,8 @@ KDDISABIO console ioctls. Signed-off-by: Matthew Garrett Signed-off-by: David Howells Reviewed-by: Thomas Gleixner -Reviewed-by: "Lee, Chun-Yi" cc: x86@kernel.org +Signed-off-by: Matthew Garrett --- arch/x86/kernel/ioport.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) @@ -828,12 +886,12 @@ index 0fe1c8782208..abc702a6ae9c 100644 } regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | -- -2.20.1 +2.21.0 -From 6efd2de8172dac74fbea76d7205657c4cf22ef6a Mon Sep 17 00:00:00 2001 +From 8138905c5c6ff3c6a54913a41a658c17496de070 Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: Mon, 9 Apr 2018 09:52:48 +0100 -Subject: [PATCH 09/22] x86/msr: Restrict MSR access when the kernel is locked +Date: Mon, 18 Feb 2019 12:44:59 +0000 +Subject: [PATCH 12/27] x86/msr: Restrict MSR access when the kernel is locked down Writing to MSRs should not be allowed if the kernel is locked down, since @@ -847,8 +905,8 @@ Signed-off-by: Matthew Garrett Signed-off-by: David Howells Acked-by: Kees Cook Reviewed-by: Thomas Gleixner -Reviewed-by: "Lee, Chun-Yi" cc: x86@kernel.org +Signed-off-by: Matthew Garrett --- arch/x86/kernel/msr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) @@ -882,12 +940,12 @@ index 4588414e2561..f5a2cf07972f 100644 if (err) break; -- -2.20.1 +2.21.0 -From 7e4c9369ca56ec7508ad851fb3f8af7b7e83c4e5 Mon Sep 17 00:00:00 2001 +From 8f7a5950f729e8eb182a260286155940d8cdfe40 Mon Sep 17 00:00:00 2001 From: Matthew Garrett -Date: Mon, 9 Apr 2018 09:52:48 +0100 -Subject: [PATCH 10/22] ACPI: Limit access to custom_method when the kernel is +Date: Mon, 18 Feb 2019 12:44:59 +0000 +Subject: [PATCH 13/27] ACPI: Limit access to custom_method when the kernel is locked down custom_method effectively allows arbitrary access to system memory, making @@ -896,14 +954,14 @@ Disable it if the kernel is locked down. Signed-off-by: Matthew Garrett Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" cc: linux-acpi@vger.kernel.org +Signed-off-by: Matthew Garrett --- drivers/acpi/custom_method.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c -index aa972dc5cb7e..af1d161f188f 100644 +index 4451877f83b6..ac8a90dc7096 100644 --- a/drivers/acpi/custom_method.c +++ b/drivers/acpi/custom_method.c @@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, @@ -917,12 +975,12 @@ index aa972dc5cb7e..af1d161f188f 100644 /* parse the table header to get the table length */ if (count <= sizeof(struct acpi_table_header)) -- -2.20.1 +2.21.0 -From 20f5e7cfa6d01d10a5bb83a6b276d6f403aa012c Mon Sep 17 00:00:00 2001 +From 72e33c3bf28a388e657955143c0cbea7afa2e522 Mon Sep 17 00:00:00 2001 From: Josh Boyer -Date: Mon, 9 Apr 2018 09:52:49 +0100 -Subject: [PATCH 11/22] acpi: Ignore acpi_rsdp kernel param when the kernel has +Date: Mon, 18 Feb 2019 12:44:59 +0000 +Subject: [PATCH 14/27] acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down This option allows userspace to pass the RSDP address to the kernel, which @@ -931,9 +989,9 @@ the option when the kernel is locked down. Signed-off-by: Josh Boyer Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" cc: Dave Young cc: linux-acpi@vger.kernel.org +Signed-off-by: Matthew Garrett --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) @@ -952,12 +1010,12 @@ index f29e427d0d1d..3e44cef7a0cd 100644 #endif pa = acpi_arch_get_root_pointer(); -- -2.20.1 +2.21.0 -From 700ce42e36ac0b7387c55d8fe13dd1dda3d4f178 Mon Sep 17 00:00:00 2001 +From 6a23b59330d20f81b610a4f140bd29f54ceb577a Mon Sep 17 00:00:00 2001 From: Linn Crosetto -Date: Mon, 9 Apr 2018 09:52:49 +0100 -Subject: [PATCH 12/22] acpi: Disable ACPI table override if the kernel is +Date: Mon, 18 Feb 2019 12:45:00 +0000 +Subject: [PATCH 15/27] acpi: Disable ACPI table override if the kernel is locked down From the kernel documentation (initrd_table_override.txt): @@ -972,17 +1030,17 @@ so do not allow ACPI tables to be overridden if the kernel is locked down. Signed-off-by: Linn Crosetto Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" cc: linux-acpi@vger.kernel.org +Signed-off-by: Matthew Garrett --- drivers/acpi/tables.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c -index 8fccbe49612a..1794f5b4afae 100644 +index 48eabb6c2d4f..f3b4117cd8f3 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c -@@ -539,6 +539,11 @@ void __init acpi_table_upgrade(void) +@@ -531,6 +531,11 @@ void __init acpi_table_upgrade(void) if (table_nr == 0) return; @@ -995,12 +1053,12 @@ index 8fccbe49612a..1794f5b4afae 100644 memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS, all_tables_size, PAGE_SIZE); -- -2.20.1 +2.21.0 -From 795cc6dc11944a24309cd29b02efc6ff6eea241e Mon Sep 17 00:00:00 2001 +From 97f806b68d7286ec7026f802c22c5fb5a6311a45 Mon Sep 17 00:00:00 2001 From: Linn Crosetto -Date: Mon, 9 Apr 2018 09:52:50 +0100 -Subject: [PATCH 13/22] acpi: Disable APEI error injection if the kernel is +Date: Mon, 18 Feb 2019 12:45:00 +0000 +Subject: [PATCH 16/27] acpi: Disable APEI error injection if the kernel is locked down ACPI provides an error injection mechanism, EINJ, for debugging and testing @@ -1020,14 +1078,14 @@ the kernel is locked down. Signed-off-by: Linn Crosetto Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" cc: linux-acpi@vger.kernel.org +Signed-off-by: Matthew Garrett --- drivers/acpi/apei/einj.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c -index 2d4be94f8c00..6ee4ad207e8b 100644 +index fcccbfdbdd1a..9fe6bbab2e7d 100644 --- a/drivers/acpi/apei/einj.c +++ b/drivers/acpi/apei/einj.c @@ -518,6 +518,9 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2, @@ -1041,12 +1099,12 @@ index 2d4be94f8c00..6ee4ad207e8b 100644 if (flags && (flags & ~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF))) -- -2.20.1 +2.21.0 -From fbdf91419289d47c747d5535bb92a8923a0fce97 Mon Sep 17 00:00:00 2001 +From afc8d146b3f5a9a24338bd6588c55b6e70024f87 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:37 +0100 -Subject: [PATCH 14/22] Prohibit PCMCIA CIS storage when the kernel is locked +Date: Mon, 18 Feb 2019 12:45:00 +0000 +Subject: [PATCH 17/27] Prohibit PCMCIA CIS storage when the kernel is locked down Prohibit replacement of the PCMCIA Card Information Structure when the @@ -1055,6 +1113,7 @@ kernel is locked down. Suggested-by: Dominik Brodowski Signed-off-by: David Howells cc: linux-pcmcia@lists.infradead.org +Signed-off-by: Matthew Garrett --- drivers/pcmcia/cistpl.c | 3 +++ 1 file changed, 3 insertions(+) @@ -1074,12 +1133,12 @@ index ac0672b8dfca..8adf092d0e18 100644 if (off) -- -2.20.1 +2.21.0 -From 9a3726b9bf16e62fce77570c972857abc303fcd1 Mon Sep 17 00:00:00 2001 +From ff1d4a9114a86373a24fe52b0b5a9503ad4fab1b Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:37 +0100 -Subject: [PATCH 15/22] Lock down TIOCSSERIAL +Date: Mon, 18 Feb 2019 12:45:00 +0000 +Subject: [PATCH 18/27] Lock down TIOCSSERIAL Lock down TIOCSSERIAL as that can be used to change the ioport and irq settings on a serial port. This only appears to be an issue for the serial @@ -1089,15 +1148,17 @@ ignore attempts to change port/irq or give an error. Reported-by: Greg Kroah-Hartman Signed-off-by: David Howells cc: Jiri Slaby +Cc: linux-serial@vger.kernel.org +Signed-off-by: Matthew Garrett --- drivers/tty/serial/serial_core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c -index 351843f847c0..3cffe2f5d132 100644 +index d4cca5bdaf1c..04534877b575 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c -@@ -852,6 +852,12 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, +@@ -842,6 +842,12 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, new_flags = (__force upf_t)new_info->flags; old_custom_divisor = uport->custom_divisor; @@ -1111,12 +1172,12 @@ index 351843f847c0..3cffe2f5d132 100644 retval = -EPERM; if (change_irq || change_port || -- -2.20.1 +2.21.0 -From 3602dd89747ed890d31fcb4d64a3fcd48490fff7 Mon Sep 17 00:00:00 2001 +From 2465b843e56020672d9704d3ab925a0399184e36 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:37 +0100 -Subject: [PATCH 16/22] Lock down module params that specify hardware +Date: Mon, 18 Feb 2019 12:45:01 +0000 +Subject: [PATCH 19/27] Lock down module params that specify hardware parameters (eg. ioport) Provided an annotation for module parameters that specify hardware @@ -1125,6 +1186,7 @@ dma buffers and other types). Suggested-by: Alan Cox Signed-off-by: David Howells +Signed-off-by: Matthew Garrett --- kernel/params.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) @@ -1194,12 +1256,12 @@ index ce89f757e6da..8ac751c938f8 100644 if (!err) return len; -- -2.20.1 +2.21.0 -From 5c8a455102b3ca36e84694d888fad219726bd268 Mon Sep 17 00:00:00 2001 +From 7b4a19032dfd343a927c2fa4b1cd83a2d0c81bc0 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:38 +0100 -Subject: [PATCH 17/22] x86/mmiotrace: Lock down the testmmiotrace module +Date: Mon, 18 Feb 2019 12:45:01 +0000 +Subject: [PATCH 20/27] x86/mmiotrace: Lock down the testmmiotrace module The testmmiotrace module shouldn't be permitted when the kernel is locked down as it can be used to arbitrarily read and write MMIO space. @@ -1211,6 +1273,7 @@ cc: Steven Rostedt cc: Ingo Molnar cc: "H. Peter Anvin" cc: x86@kernel.org +Signed-off-by: Matthew Garrett --- arch/x86/mm/testmmiotrace.c | 3 +++ 1 file changed, 3 insertions(+) @@ -1230,18 +1293,19 @@ index f6ae6830b341..bbaad357f5d7 100644 pr_err("you have to use the module argument mmio_address.\n"); pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n"); -- -2.20.1 +2.21.0 -From 711e6f9ef237fd513eddfc1f0e3796c419bc138e Mon Sep 17 00:00:00 2001 +From a7e2f1bfd9eda4cde25effdd7e663b68e31a36cf Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:38 +0100 -Subject: [PATCH 18/22] Lock down /proc/kcore +Date: Mon, 18 Feb 2019 12:45:02 +0000 +Subject: [PATCH 21/27] Lock down /proc/kcore Disallow access to /proc/kcore when the kernel is locked down to prevent access to cryptographic data. Signed-off-by: David Howells Reviewed-by: James Morris +Signed-off-by: Matthew Garrett --- fs/proc/kcore.c | 2 ++ 1 file changed, 2 insertions(+) @@ -1260,12 +1324,12 @@ index bbcc185062bb..d50ebfbf3dbb 100644 return -EPERM; -- -2.20.1 +2.21.0 -From f2a835a43a6463abfe6781156ebdb7346d7a3c51 Mon Sep 17 00:00:00 2001 +From 0b8b0a68642ba0dedb57f7c734a7cc84d96cd30c Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:38 +0100 -Subject: [PATCH 19/22] Lock down kprobes +Date: Mon, 18 Feb 2019 12:45:02 +0000 +Subject: [PATCH 22/27] Lock down kprobes Disallow the creation of kprobes when the kernel is locked down by preventing their registration. This prevents kprobes from being used to @@ -1273,15 +1337,20 @@ access kernel memory, either to make modifications or to steal crypto data. Reported-by: Alexei Starovoitov Signed-off-by: David Howells +Signed-off-by: Matthew Garrett +Cc: Naveen N. Rao +Cc: Anil S Keshavamurthy +Cc: davem@davemloft.net +Cc: Masami Hiramatsu --- kernel/kprobes.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/kprobes.c b/kernel/kprobes.c -index c83e54727131..743c40bd1982 100644 +index f4ddfdd2d07e..6f66cca8e2c6 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c -@@ -1571,6 +1571,9 @@ int register_kprobe(struct kprobe *p) +@@ -1552,6 +1552,9 @@ int register_kprobe(struct kprobe *p) struct module *probed_mod; kprobe_opcode_t *addr; @@ -1292,26 +1361,72 @@ index c83e54727131..743c40bd1982 100644 addr = kprobe_addr(p); if (IS_ERR(addr)) -- -2.20.1 +2.21.0 -From 23afb750c60b6b2d8025eb4d52ce6ff565ca1a63 Mon Sep 17 00:00:00 2001 +From 2128009ce3291b0c4ced8672e68c6b57fc0202a8 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:38 +0100 -Subject: [PATCH 20/22] Lock down perf +Date: Mon, 18 Feb 2019 12:45:02 +0000 +Subject: [PATCH 23/27] bpf: Restrict kernel image access functions when the + kernel is locked down + +There are some bpf functions can be used to read kernel memory: +bpf_probe_read, bpf_probe_write_user and bpf_trace_printk. These allow +private keys in kernel memory (e.g. the hibernation image signing key) to +be read by an eBPF program and kernel memory to be altered without +restriction. + +Completely prohibit the use of BPF when the kernel is locked down. + +Suggested-by: Alexei Starovoitov +Signed-off-by: David Howells +cc: netdev@vger.kernel.org +cc: Chun-Yi Lee +cc: Alexei Starovoitov +Cc: Daniel Borkmann +Signed-off-by: Matthew Garrett +--- + kernel/bpf/syscall.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index b155cd17c1bd..2cde39a875aa 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2585,6 +2585,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz + if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN)) + return -EPERM; + ++ if (kernel_is_locked_down("BPF")) ++ return -EPERM; ++ + err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size); + if (err) + return err; +-- +2.21.0 + +From 2fba6ffa91430a0c2a3177c6a5a0982deb966781 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Mon, 18 Feb 2019 12:45:02 +0000 +Subject: [PATCH 24/27] Lock down perf Disallow the use of certain perf facilities that might allow userspace to access kernel data. Signed-off-by: David Howells +Signed-off-by: Matthew Garrett +Cc: Peter Zijlstra +Cc: Ingo Molnar +Cc: Arnaldo Carvalho de Melo --- kernel/events/core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/events/core.c b/kernel/events/core.c -index 5f59d848171e..ddf0fa63cb80 100644 +index 3cd13a30f732..7748c6f39992 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c -@@ -10727,6 +10727,11 @@ SYSCALL_DEFINE5(perf_event_open, +@@ -10461,6 +10461,11 @@ SYSCALL_DEFINE5(perf_event_open, return -EINVAL; } @@ -1324,12 +1439,12 @@ index 5f59d848171e..ddf0fa63cb80 100644 if ((attr.sample_type & PERF_SAMPLE_PHYS_ADDR) && perf_paranoid_kernel() && !capable(CAP_SYS_ADMIN)) -- -2.20.1 +2.21.0 -From dc6da5e583b02c04a6e0518158ef3d82735aeb5d Mon Sep 17 00:00:00 2001 +From 8972429a68131c4e1387978697d8cd3e3a51fce2 Mon Sep 17 00:00:00 2001 From: David Howells -Date: Wed, 4 Apr 2018 14:45:38 +0100 -Subject: [PATCH 21/22] debugfs: Restrict debugfs when the kernel is locked +Date: Mon, 18 Feb 2019 12:45:02 +0000 +Subject: [PATCH 25/27] debugfs: Restrict debugfs when the kernel is locked down Disallow opening of debugfs files that might be used to muck around when @@ -1367,6 +1482,8 @@ cc: acpi4asus-user@lists.sourceforge.net cc: platform-driver-x86@vger.kernel.org cc: Matthew Garrett cc: Thomas Gleixner +Cc: Greg Kroah-Hartman +Signed-off-by: Matthew Garrett --- fs/debugfs/file.c | 28 ++++++++++++++++++++++++++++ fs/debugfs/inode.c | 30 ++++++++++++++++++++++++++++-- @@ -1426,7 +1543,7 @@ index 4fce1da7db23..c33042c1eff3 100644 if (!real_fops) { /* Huh? Module did not cleanup after itself at exit? */ diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c -index 95b5e78c22b1..ce99ea07fdb4 100644 +index 13b01351dd1c..4daec17b8215 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -32,6 +32,31 @@ static struct vfsmount *debugfs_mount; @@ -1469,7 +1586,7 @@ index 95b5e78c22b1..ce99ea07fdb4 100644 inode->i_fop = proxy_fops; dentry->d_fsdata = (void *)((unsigned long)real_fops | DEBUGFS_FSDATA_IS_REAL_FOPS_BIT); -@@ -516,7 +542,7 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) +@@ -513,7 +539,7 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) return failed_creating(dentry); inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; @@ -1478,7 +1595,7 @@ index 95b5e78c22b1..ce99ea07fdb4 100644 inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ -@@ -611,7 +637,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, +@@ -608,7 +634,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, return failed_creating(dentry); } inode->i_mode = S_IFLNK | S_IRWXUGO; @@ -1488,63 +1605,192 @@ index 95b5e78c22b1..ce99ea07fdb4 100644 d_instantiate(dentry, inode); return end_creating(dentry); -- -2.20.1 +2.21.0 -From 29131d94aceb11ad6be4b0d8820db23986f1a0b2 Mon Sep 17 00:00:00 2001 -From: Vasily Gorbik -Date: Wed, 21 Nov 2018 13:05:10 +0100 -Subject: [PATCH 22/22] debugfs: avoid EPERM when no open file operation - defined +From e9bf5c2e6f6cad9c992b5195af04d1f6500aa3ed Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Wed, 28 Feb 2018 14:43:03 +0000 +Subject: [PATCH 26/27] lockdown: Print current->comm in restriction messages -With "debugfs: Restrict debugfs when the kernel is locked down" -return code "r" is unconditionally set to -EPERM, which stays like that -until function return if no "open" file operation defined, effectivelly -resulting in "Operation not permitted" for all such files despite kernel -lock down status or CONFIG_LOCK_DOWN_KERNEL being enabled. +Print the content of current->comm in messages generated by lockdown to +indicate a restriction that was hit. This makes it a bit easier to find +out what caused the message. -In particular this breaks 2 debugfs files on s390: -/sys/kernel/debug/s390_hypfs/diag_304 -/sys/kernel/debug/s390_hypfs/diag_204 +The message now patterned something like: -To address that set EPERM return code only when debugfs_is_locked_down -returns true. + Lockdown: : is restricted; see man kernel_lockdown.7 -Fixes: 3fc322605158 ("debugfs: Restrict debugfs when the kernel is locked down") -Signed-off-by: Vasily Gorbik +Signed-off-by: David Howells +Signed-off-by: Matthew Garrett --- - fs/debugfs/file.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) + security/lock_down.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c -index c33042c1eff3..3a5033ff9ec7 100644 ---- a/fs/debugfs/file.c -+++ b/fs/debugfs/file.c -@@ -167,9 +167,10 @@ static int open_proxy_open(struct inode *inode, struct file *filp) - - real_fops = debugfs_real_fops(filp); - -- r = -EPERM; -- if (debugfs_is_locked_down(inode, filp, real_fops)) -+ if (debugfs_is_locked_down(inode, filp, real_fops)) { -+ r = -EPERM; - goto out; -+ } +diff --git a/security/lock_down.c b/security/lock_down.c +index 18d8776a4d02..ee00ca2677e7 100644 +--- a/security/lock_down.c ++++ b/security/lock_down.c +@@ -53,8 +53,8 @@ void __init init_lockdown(void) + bool __kernel_is_locked_down(const char *what, bool first) + { + if (what && first && kernel_locked_down) +- pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n", +- what); ++ pr_notice("Lockdown: %s: %s is restricted; see man kernel_lockdown.7\n", ++ current->comm, what); + return kernel_locked_down; + } + EXPORT_SYMBOL(__kernel_is_locked_down); +-- +2.21.0 + +From 1c57935ab108280aa79fe4420d4bc13e19bd38e2 Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Tue, 12 Mar 2019 12:50:30 -0700 +Subject: [PATCH 27/27] kexec: Allow kexec_file() with appropriate IMA policy + when locked down + +Systems in lockdown mode should block the kexec of untrusted kernels. +For x86 and ARM we can ensure that a kernel is trustworthy by validating +a PE signature, but this isn't possible on other architectures. On those +platforms we can use IMA digital signatures instead. Add a function to +determine whether IMA has or will verify signatures for a given event type, +and if so permit kexec_file() even if the kernel is otherwise locked down. +This is restricted to cases where CONFIG_INTEGRITY_TRUSTED_KEYRING is set +in order to prevent an attacker from loading additional keys at runtime. + +Signed-off-by: Matthew Garrett +Cc: Mimi Zohar +Cc: Dmitry Kasatkin +Cc: linux-integrity@vger.kernel.org +--- + include/linux/ima.h | 9 ++++++ + kernel/kexec_file.c | 7 +++- + security/integrity/ima/ima.h | 2 ++ + security/integrity/ima/ima_main.c | 2 +- + security/integrity/ima/ima_policy.c | 50 +++++++++++++++++++++++++++++ + 5 files changed, 68 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ima.h b/include/linux/ima.h +index b5e16b8c50b7..05921227d700 100644 +--- a/include/linux/ima.h ++++ b/include/linux/ima.h +@@ -127,4 +127,13 @@ static inline int ima_inode_removexattr(struct dentry *dentry, + return 0; + } + #endif /* CONFIG_IMA_APPRAISE */ ++ ++#if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING) ++extern bool ima_appraise_signature(enum kernel_read_file_id func); ++#else ++static inline bool ima_appraise_kexec_signature(enum kernel_read_file_id func) ++{ ++ return false; ++} ++#endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */ + #endif /* _LINUX_IMA_H */ +diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c +index 0cfe4f6f7f85..8ffa4b75c620 100644 +--- a/kernel/kexec_file.c ++++ b/kernel/kexec_file.c +@@ -240,7 +240,12 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, + + ret = 0; + +- if (kernel_is_locked_down(reason)) { ++ /* If IMA is guaranteed to appraise a signature on the kexec ++ * image, permit it even if the kernel is otherwise locked ++ * down. ++ */ ++ if (!ima_appraise_signature(READING_KEXEC_IMAGE) && ++ kernel_is_locked_down(reason)) { + ret = -EPERM; + goto out; + } +diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h +index cc12f3449a72..fe03cc6f1ca4 100644 +--- a/security/integrity/ima/ima.h ++++ b/security/integrity/ima/ima.h +@@ -115,6 +115,8 @@ struct ima_kexec_hdr { + u64 count; + }; - real_fops = fops_get(real_fops); - if (!real_fops) { -@@ -296,9 +297,10 @@ static int full_proxy_open(struct inode *inode, struct file *filp) - return r == -EIO ? -ENOENT : r; ++extern const int read_idmap[]; ++ + #ifdef CONFIG_HAVE_IMA_KEXEC + void ima_load_kexec_buffer(void); + #else +diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c +index 4ffac4f5c647..106f06dee9d1 100644 +--- a/security/integrity/ima/ima_main.c ++++ b/security/integrity/ima/ima_main.c +@@ -442,7 +442,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id) + return 0; + } - real_fops = debugfs_real_fops(filp); -- r = -EPERM; -- if (debugfs_is_locked_down(inode, filp, real_fops)) -+ if (debugfs_is_locked_down(inode, filp, real_fops)) { -+ r = -EPERM; - goto out; +-static const int read_idmap[READING_MAX_ID] = { ++const int read_idmap[READING_MAX_ID] = { + [READING_FIRMWARE] = FIRMWARE_CHECK, + [READING_FIRMWARE_PREALLOC_BUFFER] = FIRMWARE_CHECK, + [READING_MODULE] = MODULE_CHECK, +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 122797023bdb..f8f1cdb74a4f 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -1341,3 +1341,53 @@ int ima_policy_show(struct seq_file *m, void *v) + return 0; + } + #endif /* CONFIG_IMA_READ_POLICY */ ++ ++#if defined(CONFIG_IMA_APPRAISE) && defined(CONFIG_INTEGRITY_TRUSTED_KEYRING) ++/* ++ * ima_appraise_signature: whether IMA will appraise a given function using ++ * an IMA digital signature. This is restricted to cases where the kernel ++ * has a set of built-in trusted keys in order to avoid an attacker simply ++ * loading additional keys. ++ */ ++bool ima_appraise_signature(enum kernel_read_file_id id) ++{ ++ struct ima_rule_entry *entry; ++ bool found = false; ++ enum ima_hooks func; ++ ++ if (id >= READING_MAX_ID) ++ return false; ++ ++ func = read_idmap[id] ?: FILE_CHECK; ++ ++ rcu_read_lock(); ++ list_for_each_entry_rcu(entry, ima_rules, list) { ++ if (entry->action != APPRAISE) ++ continue; ++ ++ /* ++ * A generic entry will match, but otherwise require that it ++ * match the func we're looking for ++ */ ++ if (entry->func && entry->func != func) ++ continue; ++ ++ /* ++ * We require this to be a digital signature, not a raw IMA ++ * hash. ++ */ ++ if (entry->flags & IMA_DIGSIG_REQUIRED) ++ found = true; ++ ++ /* ++ * We've found a rule that matches, so break now even if it ++ * didn't require a digital signature - a later rule that does ++ * won't override it, so would be a false positive. ++ */ ++ break; + } - - real_fops = fops_get(real_fops); - if (!real_fops) { ++ ++ rcu_read_unlock(); ++ return found; ++} ++#endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */ -- -2.20.1 +2.21.0 diff --git a/efi-secureboot.patch b/efi-secureboot.patch index eb7c230..102da06 100644 --- a/efi-secureboot.patch +++ b/efi-secureboot.patch @@ -1,43 +1,3 @@ -From b96ff1fd9e94772fde7b58fd69969d1a1c87eb6d Mon Sep 17 00:00:00 2001 -From: Dave Young -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 -Signed-off-by: David Howells -Reviewed-by: "Lee, Chun-Yi" -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 b5123d0553f4ed5e734f6457696cdd30228d1eee Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 27 Feb 2018 10:04:55 +0000 @@ -221,34 +181,36 @@ cc: linux-efi@vger.kernel.org 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 +index adeee6329f55..27a54ec878bd 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c -@@ -64,6 +64,7 @@ +@@ -65,6 +65,7 @@ #include #include #include +#include - + #include #include -@@ -997,6 +998,8 @@ void __init setup_arch(char **cmdline_p) +@@ -1005,6 +1006,10 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled(EFI_BOOT)) efi_init(); - + + efi_set_secure_boot(boot_params.secure_boot); + - init_lockdown(); - ++ init_lockdown() ++ dmi_scan_machine(); -@@ -1150,8 +1154,6 @@ void __init setup_arch(char **cmdline_p) + dmi_memdev_walk(); + dmi_set_dump_stack_arch_desc(); +@@ -1159,8 +1164,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 @@ -264,13 +226,13 @@ index ce261e1765ff..7aff55b309a6 100644 return simple_setattr(dentry, ia); } diff --git a/security/Kconfig b/security/Kconfig -index 461d5acc3616..13fdada1ffc2 100644 +index 9c343f262bdd..30788bc47863 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. - +@@ -244,6 +244,20 @@ config LOCK_DOWN_KERNEL_FORCE + help + Enable the kernel lock down functionality automatically at boot. + +config LOCK_DOWN_IN_EFI_SECURE_BOOT + bool "Lock down the kernel in EFI Secure Boot mode" + default n @@ -285,31 +247,31 @@ index 461d5acc3616..13fdada1ffc2 100644 + 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" + source "security/tomoyo/Kconfig" diff --git a/security/lock_down.c b/security/lock_down.c -index 2c6b00f0c229..527f7e51dc8d 100644 +index ee00ca2677e7..bb4dc7838f3e 100644 --- a/security/lock_down.c +++ b/security/lock_down.c @@ -12,6 +12,7 @@ + + #include #include - #include - #include +#include - #include - - #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"); + + static __ro_after_init bool kernel_locked_down; + +@@ -44,6 +45,10 @@ void __init init_lockdown(void) + #ifdef CONFIG_LOCK_DOWN_FORCE + lock_kernel_down("Kernel configuration"); #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 diff --git a/kernel-i686-debug.config b/kernel-i686-debug.config index f83d950..f37c874 100644 --- a/kernel-i686-debug.config +++ b/kernel-i686-debug.config @@ -2644,7 +2644,8 @@ CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_XZ is not set # CONFIG_KEXEC_FILE is not set # CONFIG_KEXEC_JUMP is not set -CONFIG_KEXEC_VERIFY_SIG=y +# CONFIG_KEXEC_SIG_FORCE is not set +CONFIG_KEXEC_SIG=y CONFIG_KEXEC=y # CONFIG_KEYBOARD_ADC is not set # CONFIG_KEYBOARD_ADP5588 is not set @@ -2827,8 +2828,8 @@ CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_LOCKD=m # CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT is not set +# CONFIG_LOCK_DOWN_KERNEL_FORCE is not set CONFIG_LOCK_DOWN_KERNEL=y -# CONFIG_LOCK_DOWN_MANDATORY is not set CONFIG_LOCKD_V4=y CONFIG_LOCK_STAT=y CONFIG_LOCK_TORTURE_TEST=m diff --git a/kernel-i686.config b/kernel-i686.config index ae761ca..a060096 100644 --- a/kernel-i686.config +++ b/kernel-i686.config @@ -2625,7 +2625,8 @@ CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_XZ is not set # CONFIG_KEXEC_FILE is not set # CONFIG_KEXEC_JUMP is not set -CONFIG_KEXEC_VERIFY_SIG=y +# CONFIG_KEXEC_SIG_FORCE is not set +CONFIG_KEXEC_SIG=y CONFIG_KEXEC=y # CONFIG_KEYBOARD_ADC is not set # CONFIG_KEYBOARD_ADP5588 is not set @@ -2808,8 +2809,8 @@ CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_LOCKD=m # CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT is not set +# CONFIG_LOCK_DOWN_KERNEL_FORCE is not set CONFIG_LOCK_DOWN_KERNEL=y -# CONFIG_LOCK_DOWN_MANDATORY is not set CONFIG_LOCKD_V4=y # CONFIG_LOCK_STAT is not set # CONFIG_LOCK_TORTURE_TEST is not set diff --git a/kernel-x86_64-debug.config b/kernel-x86_64-debug.config index f635207..293fded 100644 --- a/kernel-x86_64-debug.config +++ b/kernel-x86_64-debug.config @@ -2701,7 +2701,8 @@ CONFIG_KERNEL_GZIP=y CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y CONFIG_KEXEC_FILE=y CONFIG_KEXEC_JUMP=y -CONFIG_KEXEC_VERIFY_SIG=y +# CONFIG_KEXEC_SIG_FORCE is not set +CONFIG_KEXEC_SIG=y CONFIG_KEXEC=y # CONFIG_KEYBOARD_ADC is not set # CONFIG_KEYBOARD_ADP5588 is not set @@ -2884,8 +2885,8 @@ CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_LOCKD=m CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y +# CONFIG_LOCK_DOWN_KERNEL_FORCE is not set CONFIG_LOCK_DOWN_KERNEL=y -# CONFIG_LOCK_DOWN_MANDATORY is not set CONFIG_LOCKD_V4=y CONFIG_LOCK_STAT=y CONFIG_LOCK_TORTURE_TEST=m diff --git a/kernel-x86_64.config b/kernel-x86_64.config index fad3cde..7fc7762 100644 --- a/kernel-x86_64.config +++ b/kernel-x86_64.config @@ -2682,7 +2682,8 @@ CONFIG_KERNEL_GZIP=y CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y CONFIG_KEXEC_FILE=y CONFIG_KEXEC_JUMP=y -CONFIG_KEXEC_VERIFY_SIG=y +# CONFIG_KEXEC_SIG_FORCE is not set +CONFIG_KEXEC_SIG=y CONFIG_KEXEC=y # CONFIG_KEYBOARD_ADC is not set # CONFIG_KEYBOARD_ADP5588 is not set @@ -2865,8 +2866,8 @@ CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_LOCKD=m CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y +# CONFIG_LOCK_DOWN_KERNEL_FORCE is not set CONFIG_LOCK_DOWN_KERNEL=y -# CONFIG_LOCK_DOWN_MANDATORY is not set CONFIG_LOCKD_V4=y # CONFIG_LOCK_STAT is not set # CONFIG_LOCK_TORTURE_TEST is not set