962ea4f
From 9079547f4808ea5c8cd844bf40d3895994bd175e Mon Sep 17 00:00:00 2001
962ea4f
From: Josh Boyer <jwboyer@fedoraproject.org>
962ea4f
Date: Mon, 21 Nov 2016 23:55:55 +0000
962ea4f
Subject: [PATCH 07/32] efi: Add EFI_SECURE_BOOT bit
962ea4f
962ea4f
UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
962ea4f
that can be passed to efi_enabled() to find out whether secure boot is
962ea4f
enabled.
962ea4f
962ea4f
This will be used by the SysRq+x handler, registered by the x86 arch, to find
962ea4f
out whether secure boot mode is enabled so that it can be disabled.
962ea4f
962ea4f
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 arch/x86/kernel/setup.c | 15 +++++++++++++++
962ea4f
 include/linux/efi.h     |  1 +
962ea4f
 2 files changed, 16 insertions(+)
962ea4f
962ea4f
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
cd3596b
index 69780ed..447905e 100644
962ea4f
--- a/arch/x86/kernel/setup.c
962ea4f
+++ b/arch/x86/kernel/setup.c
cd3596b
@@ -1182,6 +1182,7 @@ void __init setup_arch(char **cmdline_p)
cd3596b
 			pr_info("Secure boot disabled\n");
cd3596b
 			break;
cd3596b
 		case efi_secureboot_mode_enabled:
962ea4f
+			set_bit(EFI_SECURE_BOOT, &efi.flags);
cd3596b
 			pr_info("Secure boot enabled\n");
cd3596b
 			break;
cd3596b
 		default:
962ea4f
diff --git a/include/linux/efi.h b/include/linux/efi.h
cd3596b
index 94d34e0..6049600 100644
962ea4f
--- a/include/linux/efi.h
962ea4f
+++ b/include/linux/efi.h
cd3596b
@@ -1069,6 +1069,7 @@ extern int __init efi_setup_pcdp_console(char *);
962ea4f
 #define EFI_DBG			8	/* Print additional debug info at runtime */
962ea4f
 #define EFI_NX_PE_DATA		9	/* Can runtime data regions be mapped non-executable? */
cd3596b
 #define EFI_MEM_ATTR		10	/* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
cd3596b
+#define EFI_SECURE_BOOT		11	/* Are we in Secure Boot mode? */
962ea4f
962ea4f
 #ifdef CONFIG_EFI
962ea4f
 /*
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From eada0243f0b8fc21588a21c564187219dee03e3c Mon Sep 17 00:00:00 2001
962ea4f
From: David Howells <dhowells@redhat.com>
962ea4f
Date: Fri, 25 Nov 2016 11:52:05 +0000
962ea4f
Subject: [PATCH 08/32] efi: Handle secure boot from UEFI-2.6
962ea4f
962ea4f
UEFI-2.6 adds a new variable, DeployedMode.  If it exists, this must be 1
962ea4f
if we're to engage lockdown mode.
962ea4f
962ea4f
Reported-by: James Bottomley <James.Bottomley@HansenPartnership.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/firmware/efi/libstub/secureboot.c | 16 +++++++++++++++-
962ea4f
 include/linux/efi.h                       |  4 ++++
962ea4f
 2 files changed, 19 insertions(+), 1 deletion(-)
962ea4f
962ea4f
diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
962ea4f
index ba6ef71..333b159 100644
962ea4f
--- a/drivers/firmware/efi/libstub/secureboot.c
962ea4f
+++ b/drivers/firmware/efi/libstub/secureboot.c
962ea4f
@@ -22,6 +22,9 @@ static const efi_char16_t const efi_SecureBoot_name[] = {
962ea4f
 static const efi_char16_t const efi_SetupMode_name[] = {
962ea4f
 	'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0
962ea4f
 };
962ea4f
+static const efi_char16_t const efi_DeployedMode_name[] = {
962ea4f
+	'D', 'e', 'p', 'l', 'o', 'y', 'e', 'd', 'M', 'o', 'd', 'e', 0
962ea4f
+};
962ea4f
962ea4f
 /* SHIM variables */
962ea4f
 static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
962ea4f
@@ -40,7 +43,7 @@ static efi_char16_t const shim_MokSBState_name[] = {
962ea4f
 enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg)
962ea4f
 {
962ea4f
 	u32 attr;
962ea4f
-	u8 secboot, setupmode, moksbstate;
962ea4f
+	u8 secboot, setupmode, deployedmode, moksbstate;
962ea4f
 	unsigned long size;
962ea4f
 	efi_status_t status;
962ea4f
cd3596b
@@ -57,6 +57,17 @@ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table_arg)
962ea4f
 	if (secboot == 0 || setupmode == 1)
cd3596b
 		return efi_secureboot_mode_disabled;
962ea4f
962ea4f
+	/* UEFI-2.6 requires DeployedMode to be 1. */
962ea4f
+	if (sys_table_arg->hdr.revision >= EFI_2_60_SYSTEM_TABLE_REVISION) {
962ea4f
+		size = sizeof(deployedmode);
962ea4f
+		status = get_efi_var(efi_DeployedMode_name, &efi_variable_guid,
962ea4f
+				     NULL, &size, &deployedmode);
962ea4f
+		if (status != EFI_SUCCESS)
962ea4f
+			goto out_efi_err;
962ea4f
+		if (deployedmode == 0)
cd3596b
+			return efi_secureboot_mode_disabled;
962ea4f
+	}
962ea4f
+
cd3596b
 	/*
cd3596b
 	 * See if a user has put the shim into insecure mode. If so, and if the
962ea4f
 	 * variable doesn't have the runtime attribute set, we might as well
962ea4f
 	 * honor that.
962ea4f
diff --git a/include/linux/efi.h b/include/linux/efi.h
962ea4f
index 135ca9c..e1893f5 100644
962ea4f
--- a/include/linux/efi.h
962ea4f
+++ b/include/linux/efi.h
962ea4f
@@ -645,6 +645,10 @@ typedef struct {
962ea4f
962ea4f
 #define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
962ea4f
962ea4f
+#define EFI_2_60_SYSTEM_TABLE_REVISION  ((2 << 16) | (60))
962ea4f
+#define EFI_2_50_SYSTEM_TABLE_REVISION  ((2 << 16) | (50))
962ea4f
+#define EFI_2_40_SYSTEM_TABLE_REVISION  ((2 << 16) | (40))
962ea4f
+#define EFI_2_31_SYSTEM_TABLE_REVISION  ((2 << 16) | (31))
962ea4f
 #define EFI_2_30_SYSTEM_TABLE_REVISION  ((2 << 16) | (30))
962ea4f
 #define EFI_2_20_SYSTEM_TABLE_REVISION  ((2 << 16) | (20))
962ea4f
 #define EFI_2_10_SYSTEM_TABLE_REVISION  ((2 << 16) | (10))
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 3b0695eda22ad712a2b9be9bb70979d875a37816 Mon Sep 17 00:00:00 2001
962ea4f
From: David Howells <dhowells@redhat.com>
962ea4f
Date: Mon, 21 Nov 2016 23:36:17 +0000
962ea4f
Subject: [PATCH 09/32] Add the ability to lock down access to the running
962ea4f
 kernel image
962ea4f
962ea4f
Provide a single call to allow kernel code to determine whether the system
962ea4f
should be locked down, thereby disallowing various accesses that might
962ea4f
allow the running kernel image to be changed including the loading of
962ea4f
modules that aren't validly signed with a key we recognise, fiddling with
962ea4f
MSR registers and disallowing hibernation,
962ea4f
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 include/linux/kernel.h   |  9 +++++++++
962ea4f
 include/linux/security.h | 11 +++++++++++
962ea4f
 security/Kconfig         | 15 +++++++++++++++
962ea4f
 security/Makefile        |  3 +++
962ea4f
 security/lock_down.c     | 40 ++++++++++++++++++++++++++++++++++++++++
962ea4f
 5 files changed, 78 insertions(+)
962ea4f
 create mode 100644 security/lock_down.c
962ea4f
962ea4f
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
962ea4f
index bc6ed52..8ab309d 100644
962ea4f
--- a/include/linux/kernel.h
962ea4f
+++ b/include/linux/kernel.h
962ea4f
@@ -268,6 +268,15 @@ extern int oops_may_print(void);
962ea4f
 void do_exit(long error_code) __noreturn;
962ea4f
 void complete_and_exit(struct completion *, long) __noreturn;
962ea4f
962ea4f
+#ifdef CONFIG_LOCK_DOWN_KERNEL
962ea4f
+extern bool kernel_is_locked_down(void);
962ea4f
+#else
962ea4f
+static inline bool kernel_is_locked_down(void)
962ea4f
+{
962ea4f
+	return false;
962ea4f
+}
962ea4f
+#endif
962ea4f
+
962ea4f
 /* Internal, do not use. */
962ea4f
 int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
962ea4f
 int __must_check _kstrtol(const char *s, unsigned int base, long *res);
962ea4f
diff --git a/include/linux/security.h b/include/linux/security.h
962ea4f
index c2125e9..41a7325 100644
962ea4f
--- a/include/linux/security.h
962ea4f
+++ b/include/linux/security.h
962ea4f
@@ -1685,5 +1685,16 @@ static inline void free_secdata(void *secdata)
962ea4f
 { }
962ea4f
 #endif /* CONFIG_SECURITY */
962ea4f
962ea4f
+#ifdef CONFIG_LOCK_DOWN_KERNEL
962ea4f
+extern void lock_kernel_down(void);
962ea4f
+#ifdef CONFIG_ALLOW_LOCKDOWN_LIFT
962ea4f
+extern void lift_kernel_lockdown(void);
962ea4f
+#endif
962ea4f
+#else
962ea4f
+static inline void lock_kernel_down(void)
962ea4f
+{
962ea4f
+}
962ea4f
+#endif
962ea4f
+
962ea4f
 #endif /* ! __LINUX_SECURITY_H */
962ea4f
962ea4f
diff --git a/security/Kconfig b/security/Kconfig
962ea4f
index 118f454..fa1a678 100644
962ea4f
--- a/security/Kconfig
962ea4f
+++ b/security/Kconfig
962ea4f
@@ -158,6 +158,21 @@ config HARDENED_USERCOPY_PAGESPAN
962ea4f
 	  been removed. This config is intended to be used only while
962ea4f
 	  trying to find such users.
962ea4f
962ea4f
+config LOCK_DOWN_KERNEL
962ea4f
+	bool "Allow the kernel to be 'locked down'"
962ea4f
+	help
962ea4f
+	  Allow the kernel to be locked down under certain circumstances, for
962ea4f
+	  instance if UEFI secure boot is enabled.  Locking down the kernel
962ea4f
+	  turns off various features that might otherwise allow access to the
962ea4f
+	  kernel image (eg. setting MSR registers).
962ea4f
+
962ea4f
+config ALLOW_LOCKDOWN_LIFT
962ea4f
+	bool
962ea4f
+	help
962ea4f
+	  Allow the lockdown on a kernel to be lifted, thereby restoring the
962ea4f
+	  ability of userspace to access the kernel image (eg. by SysRq+x under
962ea4f
+	  x86).
962ea4f
+
962ea4f
 source security/selinux/Kconfig
962ea4f
 source security/smack/Kconfig
962ea4f
 source security/tomoyo/Kconfig
962ea4f
diff --git a/security/Makefile b/security/Makefile
962ea4f
index f2d71cd..8c4a43e 100644
962ea4f
--- a/security/Makefile
962ea4f
+++ b/security/Makefile
962ea4f
@@ -29,3 +29,6 @@ obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
962ea4f
 # Object integrity file lists
962ea4f
 subdir-$(CONFIG_INTEGRITY)		+= integrity
962ea4f
 obj-$(CONFIG_INTEGRITY)			+= integrity/
962ea4f
+
962ea4f
+# Allow the kernel to be locked down
962ea4f
+obj-$(CONFIG_LOCK_DOWN_KERNEL)		+= lock_down.o
962ea4f
diff --git a/security/lock_down.c b/security/lock_down.c
962ea4f
new file mode 100644
962ea4f
index 0000000..5788c60
962ea4f
--- /dev/null
962ea4f
+++ b/security/lock_down.c
962ea4f
@@ -0,0 +1,40 @@
962ea4f
+/* Lock down the kernel
962ea4f
+ *
962ea4f
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
962ea4f
+ * Written by David Howells (dhowells@redhat.com)
962ea4f
+ *
962ea4f
+ * This program is free software; you can redistribute it and/or
962ea4f
+ * modify it under the terms of the GNU General Public Licence
962ea4f
+ * as published by the Free Software Foundation; either version
962ea4f
+ * 2 of the Licence, or (at your option) any later version.
962ea4f
+ */
962ea4f
+
962ea4f
+#include <linux/security.h>
962ea4f
+#include <linux/export.h>
962ea4f
+
962ea4f
+static __read_mostly bool kernel_locked_down;
962ea4f
+
962ea4f
+/*
962ea4f
+ * Put the kernel into lock-down mode.
962ea4f
+ */
962ea4f
+void lock_kernel_down(void)
962ea4f
+{
962ea4f
+	kernel_locked_down = true;
962ea4f
+}
962ea4f
+
962ea4f
+/*
962ea4f
+ * Take the kernel out of lockdown mode.
962ea4f
+ */
962ea4f
+void lift_kernel_lockdown(void)
962ea4f
+{
962ea4f
+	kernel_locked_down = false;
962ea4f
+}
962ea4f
+
962ea4f
+/**
962ea4f
+ * kernel_is_locked_down - Find out if the kernel is locked down
962ea4f
+ */
962ea4f
+bool kernel_is_locked_down(void)
962ea4f
+{
962ea4f
+	return kernel_locked_down;
962ea4f
+}
962ea4f
+EXPORT_SYMBOL(kernel_is_locked_down);
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From c1cc643f82e1c9efee123eb81befb58e41b87310 Mon Sep 17 00:00:00 2001
962ea4f
From: David Howells <dhowells@redhat.com>
962ea4f
Date: Mon, 21 Nov 2016 23:55:55 +0000
962ea4f
Subject: [PATCH 10/32] efi: Lock down the kernel if booted in secure boot mode
962ea4f
962ea4f
UEFI Secure Boot provides a mechanism for ensuring that the firmware will
962ea4f
only load signed bootloaders and kernels.  Certain use cases may also
962ea4f
require that all kernel modules also be signed.  Add a configuration option
962ea4f
that to lock down the kernel - which includes requiring validly signed
962ea4f
modules - if the kernel is secure-booted.
962ea4f
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 arch/x86/Kconfig        | 12 ++++++++++++
962ea4f
 arch/x86/kernel/setup.c |  8 +++++++-
962ea4f
 2 files changed, 19 insertions(+), 1 deletion(-)
962ea4f
962ea4f
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
962ea4f
index bada636..5b19997 100644
962ea4f
--- a/arch/x86/Kconfig
962ea4f
+++ b/arch/x86/Kconfig
962ea4f
@@ -1786,6 +1786,18 @@ config EFI_MIXED
962ea4f
962ea4f
 	   If unsure, say N.
962ea4f
962ea4f
+config EFI_SECURE_BOOT_LOCK_DOWN
962ea4f
+	def_bool n
962ea4f
+	depends on EFI
962ea4f
+	prompt "Lock down the kernel when UEFI Secure Boot is enabled"
962ea4f
+	---help---
962ea4f
+	  UEFI Secure Boot provides a mechanism for ensuring that the firmware
962ea4f
+	  will only load signed bootloaders and kernels.  Certain use cases may
962ea4f
+	  also require that all kernel modules also be signed and that
962ea4f
+	  userspace is prevented from directly changing the running kernel
962ea4f
+	  image.  Say Y here to automatically lock down the kernel when a
962ea4f
+	  system boots with UEFI Secure Boot enabled.
962ea4f
+
962ea4f
 config SECCOMP
962ea4f
 	def_bool y
962ea4f
 	prompt "Enable seccomp to safely compute untrusted bytecode"
962ea4f
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
962ea4f
index d8972ec..facaeb9 100644
962ea4f
--- a/arch/x86/kernel/setup.c
962ea4f
+++ b/arch/x86/kernel/setup.c
962ea4f
@@ -69,6 +69,7 @@
962ea4f
 #include <linux/crash_dump.h>
962ea4f
 #include <linux/tboot.h>
962ea4f
 #include <linux/jiffies.h>
962ea4f
+#include <linux/security.h>
962ea4f
962ea4f
 #include <video/edid.h>
962ea4f
962ea4f
@@ -1159,7 +1160,12 @@ void __init setup_arch(char **cmdline_p)
962ea4f
 			break;
962ea4f
 		case efi_secureboot_mode_enabled:
962ea4f
 			set_bit(EFI_SECURE_BOOT, &efi.flags);
962ea4f
-			pr_info("Secure boot enabled\n");
962ea4f
+			if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT_LOCK_DOWN)) {
962ea4f
+				lock_kernel_down();
962ea4f
+				pr_info("Secure boot enabled and kernel locked down\n");
962ea4f
+			} else {
962ea4f
+				pr_info("Secure boot enabled\n");
962ea4f
+			}
962ea4f
 			break;
962ea4f
 		default:
962ea4f
 			pr_info("Secure boot could not be determined\n");
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 03ff1bcf82c3acc3df8e8fd1badbbc9f6a27a2e6 Mon Sep 17 00:00:00 2001
962ea4f
From: David Howells <dhowells@redhat.com>
962ea4f
Date: Wed, 23 Nov 2016 13:22:22 +0000
962ea4f
Subject: [PATCH 11/32] Enforce module signatures if the kernel is locked down
962ea4f
962ea4f
If the kernel is locked down, require that all modules have valid
962ea4f
signatures that we can verify.
962ea4f
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 kernel/module.c | 2 +-
962ea4f
 1 file changed, 1 insertion(+), 1 deletion(-)
962ea4f
962ea4f
diff --git a/kernel/module.c b/kernel/module.c
962ea4f
index f57dd63..2a021c3 100644
962ea4f
--- a/kernel/module.c
962ea4f
+++ b/kernel/module.c
962ea4f
@@ -2744,7 +2744,7 @@ static int module_sig_check(struct load_info *info, int flags)
962ea4f
 	}
962ea4f
962ea4f
 	/* Not having a signature is only an error if we're strict. */
962ea4f
-	if (err == -ENOKEY && !sig_enforce)
962ea4f
+	if (err == -ENOKEY && !sig_enforce && !kernel_is_locked_down())
962ea4f
 		err = 0;
962ea4f
962ea4f
 	return err;
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 328104a3a9859084a25240ea031572e0d20ceaf4 Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:16 +0000
962ea4f
Subject: [PATCH 12/32] Restrict /dev/mem and /dev/kmem when the kernel is
962ea4f
 locked down
962ea4f
962ea4f
Allowing users to write to address space makes it possible for the kernel to
962ea4f
be subverted, avoiding module loading restrictions.  Prevent this when the
962ea4f
kernel has been locked down.
962ea4f
962ea4f
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/char/mem.c | 6 ++++++
962ea4f
 1 file changed, 6 insertions(+)
962ea4f
962ea4f
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
962ea4f
index 5bb1985..6441d21 100644
962ea4f
--- a/drivers/char/mem.c
962ea4f
+++ b/drivers/char/mem.c
962ea4f
@@ -163,6 +163,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
962ea4f
 	if (p != *ppos)
962ea4f
 		return -EFBIG;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	if (!valid_phys_addr_range(p, count))
962ea4f
 		return -EFAULT;
962ea4f
962ea4f
@@ -515,6 +518,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
411d3b7
 	char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
411d3b7
 	int err = 0;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	if (p < (unsigned long) high_memory) {
962ea4f
 		unsigned long to_write = min_t(unsigned long, count,
962ea4f
 					       (unsigned long)high_memory - p);
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 2cfe484bdc7e42b42be4887f2b4d23ac9de79593 Mon Sep 17 00:00:00 2001
962ea4f
From: Kyle McMartin <kyle@redhat.com>
962ea4f
Date: Mon, 21 Nov 2016 23:55:56 +0000
962ea4f
Subject: [PATCH 13/32] Add a sysrq option to exit secure boot mode
962ea4f
962ea4f
Make sysrq+x exit secure boot mode on x86_64, thereby allowing the running
962ea4f
kernel image to be modified.  This lifts the lockdown.
962ea4f
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 arch/x86/Kconfig            | 10 ++++++++++
962ea4f
 arch/x86/kernel/setup.c     | 31 +++++++++++++++++++++++++++++++
962ea4f
 drivers/input/misc/uinput.c |  1 +
962ea4f
 drivers/tty/sysrq.c         | 19 +++++++++++++------
962ea4f
 include/linux/input.h       |  5 +++++
962ea4f
 include/linux/sysrq.h       |  8 +++++++-
962ea4f
 kernel/debug/kdb/kdb_main.c |  2 +-
962ea4f
 7 files changed, 68 insertions(+), 8 deletions(-)
962ea4f
962ea4f
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
962ea4f
index 5b19997..c2b481b 100644
962ea4f
--- a/arch/x86/Kconfig
962ea4f
+++ b/arch/x86/Kconfig
962ea4f
@@ -1798,6 +1798,16 @@ config EFI_SECURE_BOOT_LOCK_DOWN
962ea4f
 	  image.  Say Y here to automatically lock down the kernel when a
962ea4f
 	  system boots with UEFI Secure Boot enabled.
962ea4f
962ea4f
+config EFI_ALLOW_SECURE_BOOT_EXIT
962ea4f
+	def_bool n
962ea4f
+	depends on EFI_SECURE_BOOT_LOCK_DOWN && MAGIC_SYSRQ
962ea4f
+	select ALLOW_LOCKDOWN_LIFT
962ea4f
+	prompt "Allow secure boot mode to be exited with SysRq+x on a keyboard"
962ea4f
+	---help---
962ea4f
+	  Allow secure boot mode to be exited and the kernel lockdown lifted by
962ea4f
+	  typing SysRq+x on a keyboard attached to the system (not permitted
962ea4f
+	  through procfs).
962ea4f
+
962ea4f
 config SECCOMP
962ea4f
 	def_bool y
962ea4f
 	prompt "Enable seccomp to safely compute untrusted bytecode"
962ea4f
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
962ea4f
index facaeb9..de24041 100644
962ea4f
--- a/arch/x86/kernel/setup.c
962ea4f
+++ b/arch/x86/kernel/setup.c
962ea4f
@@ -71,6 +71,11 @@
962ea4f
 #include <linux/jiffies.h>
962ea4f
 #include <linux/security.h>
962ea4f
962ea4f
+#include <linux/fips.h>
962ea4f
+#include <linux/cred.h>
962ea4f
+#include <linux/sysrq.h>
962ea4f
+#include <linux/init_task.h>
962ea4f
+
962ea4f
 #include <video/edid.h>
962ea4f
962ea4f
 #include <asm/mtrr.h>
962ea4f
@@ -1304,6 +1309,32 @@ void __init i386_reserve_resources(void)
962ea4f
962ea4f
 #endif /* CONFIG_X86_32 */
962ea4f
962ea4f
+#ifdef CONFIG_EFI_ALLOW_SECURE_BOOT_EXIT
962ea4f
+
962ea4f
+static void sysrq_handle_secure_boot(int key)
962ea4f
+{
962ea4f
+	if (!efi_enabled(EFI_SECURE_BOOT))
962ea4f
+		return;
962ea4f
+
962ea4f
+	pr_info("Secure boot disabled\n");
962ea4f
+	lift_kernel_lockdown();
962ea4f
+}
962ea4f
+static struct sysrq_key_op secure_boot_sysrq_op = {
962ea4f
+	.handler	=	sysrq_handle_secure_boot,
962ea4f
+	.help_msg	=	"unSB(x)",
962ea4f
+	.action_msg	=	"Disabling Secure Boot restrictions",
962ea4f
+	.enable_mask	=	SYSRQ_DISABLE_USERSPACE,
962ea4f
+};
962ea4f
+static int __init secure_boot_sysrq(void)
962ea4f
+{
962ea4f
+	if (efi_enabled(EFI_SECURE_BOOT))
962ea4f
+		register_sysrq_key('x', &secure_boot_sysrq_op);
962ea4f
+	return 0;
962ea4f
+}
962ea4f
+late_initcall(secure_boot_sysrq);
962ea4f
+#endif /*CONFIG_EFI_ALLOW_SECURE_BOOT_EXIT*/
962ea4f
+
962ea4f
+
962ea4f
 static struct notifier_block kernel_offset_notifier = {
962ea4f
 	.notifier_call = dump_kernel_offset
962ea4f
 };
962ea4f
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
962ea4f
index 92595b9..894ed3f 100644
962ea4f
--- a/drivers/input/misc/uinput.c
962ea4f
+++ b/drivers/input/misc/uinput.c
962ea4f
@@ -379,6 +379,7 @@ static int uinput_allocate_device(struct uinput_device *udev)
962ea4f
 	if (!udev->dev)
962ea4f
 		return -ENOMEM;
962ea4f
962ea4f
+	udev->dev->flags |= INPUTDEV_FLAGS_SYNTHETIC;
962ea4f
 	udev->dev->event = uinput_dev_event;
962ea4f
 	input_set_drvdata(udev->dev, udev);
962ea4f
962ea4f
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c
962ea4f
index 52bbd27..72f46a1 100644
962ea4f
--- a/drivers/tty/sysrq.c
962ea4f
+++ b/drivers/tty/sysrq.c
962ea4f
@@ -479,6 +479,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
962ea4f
 	/* x: May be registered on mips for TLB dump */
962ea4f
 	/* x: May be registered on ppc/powerpc for xmon */
962ea4f
 	/* x: May be registered on sparc64 for global PMU dump */
962ea4f
+	/* x: May be registered on x86_64 for disabling secure boot */
962ea4f
 	NULL,				/* x */
962ea4f
 	/* y: May be registered on sparc64 for global register dump */
962ea4f
 	NULL,				/* y */
962ea4f
@@ -522,7 +523,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p)
962ea4f
                 sysrq_key_table[i] = op_p;
962ea4f
 }
962ea4f
962ea4f
-void __handle_sysrq(int key, bool check_mask)
962ea4f
+void __handle_sysrq(int key, unsigned int from)
962ea4f
 {
962ea4f
 	struct sysrq_key_op *op_p;
962ea4f
 	int orig_log_level;
962ea4f
@@ -542,11 +543,15 @@ void __handle_sysrq(int key, bool check_mask)
962ea4f
962ea4f
         op_p = __sysrq_get_key_op(key);
962ea4f
         if (op_p) {
962ea4f
+		/* Ban synthetic events from some sysrq functionality */
962ea4f
+		if ((from == SYSRQ_FROM_PROC || from == SYSRQ_FROM_SYNTHETIC) &&
962ea4f
+		    op_p->enable_mask & SYSRQ_DISABLE_USERSPACE)
962ea4f
+			printk("This sysrq operation is disabled from userspace.\n");
962ea4f
 		/*
962ea4f
 		 * Should we check for enabled operations (/proc/sysrq-trigger
962ea4f
 		 * should not) and is the invoked operation enabled?
962ea4f
 		 */
962ea4f
-		if (!check_mask || sysrq_on_mask(op_p->enable_mask)) {
962ea4f
+		if (from == SYSRQ_FROM_KERNEL || sysrq_on_mask(op_p->enable_mask)) {
962ea4f
 			pr_cont("%s\n", op_p->action_msg);
962ea4f
 			console_loglevel = orig_log_level;
962ea4f
 			op_p->handler(key);
962ea4f
@@ -578,7 +583,7 @@ void __handle_sysrq(int key, bool check_mask)
962ea4f
 void handle_sysrq(int key)
962ea4f
 {
962ea4f
 	if (sysrq_on())
962ea4f
-		__handle_sysrq(key, true);
962ea4f
+		__handle_sysrq(key, SYSRQ_FROM_KERNEL);
962ea4f
 }
962ea4f
 EXPORT_SYMBOL(handle_sysrq);
962ea4f
962ea4f
@@ -659,7 +664,7 @@ static void sysrq_do_reset(unsigned long _state)
962ea4f
 static void sysrq_handle_reset_request(struct sysrq_state *state)
962ea4f
 {
962ea4f
 	if (state->reset_requested)
962ea4f
-		__handle_sysrq(sysrq_xlate[KEY_B], false);
962ea4f
+		__handle_sysrq(sysrq_xlate[KEY_B], SYSRQ_FROM_KERNEL);
962ea4f
962ea4f
 	if (sysrq_reset_downtime_ms)
962ea4f
 		mod_timer(&state->keyreset_timer,
962ea4f
@@ -810,8 +815,10 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq,
962ea4f
962ea4f
 	default:
962ea4f
 		if (sysrq->active && value && value != 2) {
962ea4f
+			int from = sysrq->handle.dev->flags & INPUTDEV_FLAGS_SYNTHETIC ?
962ea4f
+					SYSRQ_FROM_SYNTHETIC : 0;
962ea4f
 			sysrq->need_reinject = false;
962ea4f
-			__handle_sysrq(sysrq_xlate[code], true);
962ea4f
+			__handle_sysrq(sysrq_xlate[code], from);
962ea4f
 		}
962ea4f
 		break;
962ea4f
 	}
962ea4f
@@ -1095,7 +1102,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
962ea4f
962ea4f
 		if (get_user(c, buf))
962ea4f
 			return -EFAULT;
962ea4f
-		__handle_sysrq(c, false);
962ea4f
+		__handle_sysrq(c, SYSRQ_FROM_PROC);
962ea4f
 	}
962ea4f
962ea4f
 	return count;
962ea4f
diff --git a/include/linux/input.h b/include/linux/input.h
962ea4f
index a65e3b2..8b03571 100644
962ea4f
--- a/include/linux/input.h
962ea4f
+++ b/include/linux/input.h
962ea4f
@@ -42,6 +42,7 @@ struct input_value {
962ea4f
  * @phys: physical path to the device in the system hierarchy
962ea4f
  * @uniq: unique identification code for the device (if device has it)
962ea4f
  * @id: id of the device (struct input_id)
962ea4f
+ * @flags: input device flags (SYNTHETIC, etc.)
962ea4f
  * @propbit: bitmap of device properties and quirks
962ea4f
  * @evbit: bitmap of types of events supported by the device (EV_KEY,
962ea4f
  *	EV_REL, etc.)
962ea4f
@@ -124,6 +125,8 @@ struct input_dev {
962ea4f
 	const char *uniq;
962ea4f
 	struct input_id id;
962ea4f
962ea4f
+	unsigned int flags;
962ea4f
+
962ea4f
 	unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
962ea4f
962ea4f
 	unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
962ea4f
@@ -190,6 +193,8 @@ struct input_dev {
962ea4f
 };
962ea4f
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
962ea4f
962ea4f
+#define	INPUTDEV_FLAGS_SYNTHETIC	0x000000001
962ea4f
+
962ea4f
 /*
962ea4f
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
962ea4f
  */
962ea4f
diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h
962ea4f
index 387fa7d..f7c52a9 100644
962ea4f
--- a/include/linux/sysrq.h
962ea4f
+++ b/include/linux/sysrq.h
962ea4f
@@ -28,6 +28,8 @@
962ea4f
 #define SYSRQ_ENABLE_BOOT	0x0080
962ea4f
 #define SYSRQ_ENABLE_RTNICE	0x0100
962ea4f
962ea4f
+#define SYSRQ_DISABLE_USERSPACE	0x00010000
962ea4f
+
962ea4f
 struct sysrq_key_op {
962ea4f
 	void (*handler)(int);
962ea4f
 	char *help_msg;
962ea4f
@@ -42,8 +44,12 @@ struct sysrq_key_op {
962ea4f
  * are available -- else NULL's).
962ea4f
  */
962ea4f
962ea4f
+#define SYSRQ_FROM_KERNEL	0x0001
962ea4f
+#define SYSRQ_FROM_PROC		0x0002
962ea4f
+#define SYSRQ_FROM_SYNTHETIC	0x0004
962ea4f
+
962ea4f
 void handle_sysrq(int key);
962ea4f
-void __handle_sysrq(int key, bool check_mask);
962ea4f
+void __handle_sysrq(int key, unsigned int from);
962ea4f
 int register_sysrq_key(int key, struct sysrq_key_op *op);
962ea4f
 int unregister_sysrq_key(int key, struct sysrq_key_op *op);
962ea4f
 struct sysrq_key_op *__sysrq_get_key_op(int key);
962ea4f
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
962ea4f
index 2a20c0d..d46d2e1 100644
962ea4f
--- a/kernel/debug/kdb/kdb_main.c
962ea4f
+++ b/kernel/debug/kdb/kdb_main.c
962ea4f
@@ -1968,7 +1968,7 @@ static int kdb_sr(int argc, const char **argv)
962ea4f
 		return KDB_ARGCOUNT;
962ea4f
962ea4f
 	kdb_trap_printk++;
962ea4f
-	__handle_sysrq(*argv[1], check_mask);
962ea4f
+	__handle_sysrq(*argv[1], check_mask ? SYSRQ_FROM_KERNEL : 0);
962ea4f
 	kdb_trap_printk--;
962ea4f
962ea4f
 	return 0;
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From a82fdfceffac8e9cdc0287d874a8ba1b9d875e70 Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:15 +0000
962ea4f
Subject: [PATCH 14/32] kexec: Disable at runtime if the kernel is locked down
962ea4f
962ea4f
kexec permits the loading and execution of arbitrary code in ring 0, which
962ea4f
is something that lock-down is meant to prevent. It makes sense to disable
962ea4f
kexec in this situation.
962ea4f
962ea4f
This does not affect kexec_file_load() which can check for a signature on the
962ea4f
image to be booted.
962ea4f
962ea4f
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 kernel/kexec.c | 7 +++++++
962ea4f
 1 file changed, 7 insertions(+)
962ea4f
962ea4f
diff --git a/kernel/kexec.c b/kernel/kexec.c
962ea4f
index 980936a..46de8e6 100644
962ea4f
--- a/kernel/kexec.c
962ea4f
+++ b/kernel/kexec.c
962ea4f
@@ -194,6 +194,13 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
962ea4f
 		return -EPERM;
962ea4f
962ea4f
 	/*
962ea4f
+	 * kexec can be used to circumvent module loading restrictions, so
962ea4f
+	 * prevent loading in that case
962ea4f
+	 */
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
+	/*
962ea4f
 	 * Verify we have a legal set of flags
962ea4f
 	 * This leaves us room for future extensions.
962ea4f
 	 */
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 43d4cec4b9acbe2954afb355cc32dbd456ca77bd Mon Sep 17 00:00:00 2001
962ea4f
From: Dave Young <dyoung@redhat.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:15 +0000
962ea4f
Subject: [PATCH 15/32] Copy secure_boot flag in boot params across kexec
962ea4f
 reboot
962ea4f
962ea4f
Kexec reboot in case secure boot being enabled does not keep the secure
962ea4f
boot mode in new kernel, so later one can load unsigned kernel via legacy
962ea4f
kexec_load.  In this state, the system is missing the protections provided
962ea4f
by secure boot.
962ea4f
962ea4f
Adding a patch to fix this by retain the secure_boot flag in original
962ea4f
kernel.
962ea4f
962ea4f
secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the
962ea4f
stub.  Fixing this issue by copying secure_boot flag across kexec reboot.
962ea4f
962ea4f
Signed-off-by: Dave Young <dyoung@redhat.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 arch/x86/kernel/kexec-bzimage64.c | 1 +
962ea4f
 1 file changed, 1 insertion(+)
962ea4f
962ea4f
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
962ea4f
index 3407b14..b843a4e 100644
962ea4f
--- a/arch/x86/kernel/kexec-bzimage64.c
962ea4f
+++ b/arch/x86/kernel/kexec-bzimage64.c
962ea4f
@@ -179,6 +179,7 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr,
962ea4f
 	if (efi_enabled(EFI_OLD_MEMMAP))
962ea4f
 		return 0;
962ea4f
962ea4f
+	params->secure_boot = boot_params.secure_boot;
962ea4f
 	ei->efi_loader_signature = current_ei->efi_loader_signature;
962ea4f
 	ei->efi_systab = current_ei->efi_systab;
962ea4f
 	ei->efi_systab_hi = current_ei->efi_systab_hi;
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 7f303a867209a3641d3da378d914967314b60254 Mon Sep 17 00:00:00 2001
962ea4f
From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
962ea4f
Date: Wed, 23 Nov 2016 13:49:19 +0000
962ea4f
Subject: [PATCH 16/32] kexec_file: Disable at runtime if securelevel has been
962ea4f
 set
962ea4f
962ea4f
When KEXEC_VERIFY_SIG is not enabled, kernel should not loads image
962ea4f
through kexec_file systemcall if securelevel has been set.
962ea4f
962ea4f
This code was showed in Matthew's patch but not in git:
962ea4f
https://lkml.org/lkml/2015/3/13/778
962ea4f
962ea4f
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
962ea4f
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 kernel/kexec_file.c | 6 ++++++
962ea4f
 1 file changed, 6 insertions(+)
962ea4f
962ea4f
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
962ea4f
index 037c321..04f48f2 100644
962ea4f
--- a/kernel/kexec_file.c
962ea4f
+++ b/kernel/kexec_file.c
962ea4f
@@ -264,6 +264,12 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
962ea4f
 	if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
962ea4f
 		return -EPERM;
962ea4f
962ea4f
+	/* Don't permit images to be loaded into trusted kernels if we're not
962ea4f
+	 * going to verify the signature on them
962ea4f
+	 */
962ea4f
+	if (!IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) && kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	/* Make sure we have a legal set of flags */
962ea4f
 	if (flags != (flags & KEXEC_FILE_FLAGS))
962ea4f
 		return -EINVAL;
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 7b42e60e328109fc2a04434c3cfedeb53eae6426 Mon Sep 17 00:00:00 2001
962ea4f
From: Josh Boyer <jwboyer@fedoraproject.org>
962ea4f
Date: Tue, 22 Nov 2016 08:46:15 +0000
962ea4f
Subject: [PATCH 17/32] hibernate: Disable when the kernel is locked down
962ea4f
962ea4f
There is currently no way to verify the resume image when returning
962ea4f
from hibernate.  This might compromise the signed modules trust model,
962ea4f
so until we can work with signed hibernate images we disable it when the
962ea4f
kernel is locked down.
962ea4f
962ea4f
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 kernel/power/hibernate.c | 2 +-
962ea4f
 1 file changed, 1 insertion(+), 1 deletion(-)
962ea4f
962ea4f
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
962ea4f
index b26dbc4..3732187 100644
962ea4f
--- a/kernel/power/hibernate.c
962ea4f
+++ b/kernel/power/hibernate.c
962ea4f
@@ -67,7 +67,7 @@ static const struct platform_hibernation_ops *hibernation_ops;
962ea4f
962ea4f
 bool hibernation_available(void)
962ea4f
 {
962ea4f
-	return (nohibernate == 0);
962ea4f
+	return nohibernate == 0 && !kernel_is_locked_down();
962ea4f
 }
962ea4f
962ea4f
 /**
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From a2a550718c501375c22f5afdead9d25225abdcd3 Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <mjg59@srcf.ucam.org>
962ea4f
Date: Wed, 23 Nov 2016 13:28:17 +0000
962ea4f
Subject: [PATCH 18/32] uswsusp: Disable when the kernel is locked down
962ea4f
962ea4f
uswsusp allows a user process to dump and then restore kernel state, which
962ea4f
makes it possible to modify the running kernel.  Disable this if the kernel
962ea4f
is locked down.
962ea4f
962ea4f
Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 kernel/power/user.c | 3 +++
962ea4f
 1 file changed, 3 insertions(+)
962ea4f
962ea4f
diff --git a/kernel/power/user.c b/kernel/power/user.c
962ea4f
index 35310b6..c9ef5e1 100644
962ea4f
--- a/kernel/power/user.c
962ea4f
+++ b/kernel/power/user.c
962ea4f
@@ -52,6 +52,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
962ea4f
 	if (!hibernation_available())
962ea4f
 		return -EPERM;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	lock_system_sleep();
962ea4f
962ea4f
 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 81204660ab5d1914cb59fb246f103288ecf9a177 Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:15 +0000
962ea4f
Subject: [PATCH 19/32] PCI: Lock down BAR access when the kernel is locked
962ea4f
 down
962ea4f
962ea4f
Any hardware that can potentially generate DMA has to be locked down in
962ea4f
order to avoid it being possible for an attacker to modify kernel code,
962ea4f
allowing them to circumvent disabled module loading or module signing.
962ea4f
Default to paranoid - in future we can potentially relax this for
962ea4f
sufficiently IOMMU-isolated devices.
962ea4f
962ea4f
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/pci/pci-sysfs.c | 9 +++++++++
962ea4f
 drivers/pci/proc.c      | 8 +++++++-
962ea4f
 drivers/pci/syscall.c   | 2 +-
962ea4f
 3 files changed, 17 insertions(+), 2 deletions(-)
962ea4f
962ea4f
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
962ea4f
index bcd10c7..02b9c9e 100644
962ea4f
--- a/drivers/pci/pci-sysfs.c
962ea4f
+++ b/drivers/pci/pci-sysfs.c
962ea4f
@@ -716,6 +716,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj,
962ea4f
 	loff_t init_off = off;
962ea4f
 	u8 *data = (u8 *) buf;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	if (off > dev->cfg_size)
962ea4f
 		return 0;
962ea4f
 	if (off + count > dev->cfg_size) {
962ea4f
@@ -1007,6 +1010,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
962ea4f
 	resource_size_t start, end;
962ea4f
 	int i;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	for (i = 0; i < PCI_ROM_RESOURCE; i++)
962ea4f
 		if (res == &pdev->resource[i])
962ea4f
 			break;
962ea4f
@@ -1106,6 +1112,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
962ea4f
 				     struct bin_attribute *attr, char *buf,
962ea4f
 				     loff_t off, size_t count)
962ea4f
 {
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
962ea4f
 }
962ea4f
962ea4f
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
962ea4f
index 2408abe..eaccf9b 100644
962ea4f
--- a/drivers/pci/proc.c
962ea4f
+++ b/drivers/pci/proc.c
962ea4f
@@ -116,6 +116,9 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf,
962ea4f
 	int size = dev->cfg_size;
962ea4f
 	int cnt;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	if (pos >= size)
962ea4f
 		return 0;
962ea4f
 	if (nbytes >= size)
962ea4f
@@ -195,6 +198,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
962ea4f
 #endif /* HAVE_PCI_MMAP */
962ea4f
 	int ret = 0;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	switch (cmd) {
962ea4f
 	case PCIIOC_CONTROLLER:
962ea4f
 		ret = pci_domain_nr(dev->bus);
962ea4f
@@ -233,7 +239,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
962ea4f
 	struct pci_filp_private *fpriv = file->private_data;
962ea4f
 	int i, ret, write_combine;
962ea4f
962ea4f
-	if (!capable(CAP_SYS_RAWIO))
962ea4f
+	if (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down())
962ea4f
 		return -EPERM;
962ea4f
962ea4f
 	/* Make sure the caller is mapping a real resource for this device */
962ea4f
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
962ea4f
index b91c4da..81544dc 100644
962ea4f
--- a/drivers/pci/syscall.c
962ea4f
+++ b/drivers/pci/syscall.c
962ea4f
@@ -92,7 +92,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
962ea4f
 	u32 dword;
962ea4f
 	int err = 0;
962ea4f
962ea4f
-	if (!capable(CAP_SYS_ADMIN))
962ea4f
+	if (!capable(CAP_SYS_ADMIN) || kernel_is_locked_down())
962ea4f
 		return -EPERM;
962ea4f
962ea4f
 	dev = pci_get_bus_and_slot(bus, dfn);
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 18f4177e0a147adccbbacb1fa95e340352228db3 Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:16 +0000
962ea4f
Subject: [PATCH 20/32] x86: Lock down IO port access when the kernel is locked
962ea4f
 down
962ea4f
962ea4f
IO port access would permit users to gain access to PCI configuration
962ea4f
registers, which in turn (on a lot of hardware) give access to MMIO
962ea4f
register space. This would potentially permit root to trigger arbitrary
962ea4f
DMA, so lock it down by default.
962ea4f
962ea4f
This also implicitly locks down the KDADDIO, KDDELIO, KDENABIO and
962ea4f
KDDISABIO console ioctls.
962ea4f
962ea4f
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 arch/x86/kernel/ioport.c | 4 ++--
962ea4f
 drivers/char/mem.c       | 2 ++
962ea4f
 2 files changed, 4 insertions(+), 2 deletions(-)
962ea4f
962ea4f
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
962ea4f
index 589b319..f0789ab 100644
962ea4f
--- a/arch/x86/kernel/ioport.c
962ea4f
+++ b/arch/x86/kernel/ioport.c
962ea4f
@@ -28,7 +28,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
962ea4f
962ea4f
 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
962ea4f
 		return -EINVAL;
962ea4f
-	if (turn_on && !capable(CAP_SYS_RAWIO))
962ea4f
+	if (turn_on && (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down()))
962ea4f
 		return -EPERM;
962ea4f
962ea4f
 	/*
962ea4f
@@ -108,7 +108,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
962ea4f
 		return -EINVAL;
962ea4f
 	/* Trying to gain more privileges? */
962ea4f
 	if (level > old) {
962ea4f
-		if (!capable(CAP_SYS_RAWIO))
962ea4f
+		if (!capable(CAP_SYS_RAWIO) || kernel_is_locked_down())
962ea4f
 			return -EPERM;
962ea4f
 	}
962ea4f
 	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
962ea4f
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
962ea4f
index 6441d21..f653c36 100644
962ea4f
--- a/drivers/char/mem.c
962ea4f
+++ b/drivers/char/mem.c
962ea4f
@@ -743,6 +743,8 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
962ea4f
962ea4f
 static int open_port(struct inode *inode, struct file *filp)
962ea4f
 {
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
 	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
962ea4f
 }
962ea4f
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From bdd2ae6c0c8ce5a4dadaa41019a6e065e9aa9128 Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:17 +0000
962ea4f
Subject: [PATCH 21/32] x86: Restrict MSR access when the kernel is locked down
962ea4f
962ea4f
Writing to MSRs should not be allowed if the kernel is locked down, since
962ea4f
it could lead to execution of arbitrary code in kernel mode.  Based on a
962ea4f
patch by Kees Cook.
962ea4f
962ea4f
Cc: Kees Cook <keescook@chromium.org>
962ea4f
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 arch/x86/kernel/msr.c | 7 +++++++
962ea4f
 1 file changed, 7 insertions(+)
962ea4f
962ea4f
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
962ea4f
index 7f3550a..90cddc1 100644
962ea4f
--- a/arch/x86/kernel/msr.c
962ea4f
+++ b/arch/x86/kernel/msr.c
962ea4f
@@ -83,6 +83,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
962ea4f
 	int err = 0;
962ea4f
 	ssize_t bytes = 0;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	if (count % 8)
962ea4f
 		return -EINVAL;	/* Invalid chunk size */
962ea4f
962ea4f
@@ -130,6 +133,10 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
962ea4f
 			err = -EBADF;
962ea4f
 			break;
962ea4f
 		}
962ea4f
+		if (kernel_is_locked_down()) {
962ea4f
+			err = -EPERM;
962ea4f
+			break;
962ea4f
+		}
962ea4f
 		if (copy_from_user(&regs, uregs, sizeof regs)) {
962ea4f
 			err = -EFAULT;
962ea4f
 			break;
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 50d0b2fd4e13f1da62d7bfabe7559cdaaceee06b Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:16 +0000
962ea4f
Subject: [PATCH 22/32] asus-wmi: Restrict debugfs interface when the kernel is
962ea4f
 locked down
962ea4f
962ea4f
We have no way of validating what all of the Asus WMI methods do on a given
962ea4f
machine - and there's a risk that some will allow hardware state to be
962ea4f
manipulated in such a way that arbitrary code can be executed in the
962ea4f
kernel, circumventing module loading restrictions.  Prevent that if the
962ea4f
kernel is locked down.
962ea4f
962ea4f
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/platform/x86/asus-wmi.c | 9 +++++++++
962ea4f
 1 file changed, 9 insertions(+)
962ea4f
962ea4f
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
962ea4f
index ce6ca31..d860017 100644
962ea4f
--- a/drivers/platform/x86/asus-wmi.c
962ea4f
+++ b/drivers/platform/x86/asus-wmi.c
962ea4f
@@ -1872,6 +1872,9 @@ static int show_dsts(struct seq_file *m, void *data)
962ea4f
 	int err;
962ea4f
 	u32 retval = -1;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
962ea4f
962ea4f
 	if (err < 0)
962ea4f
@@ -1888,6 +1891,9 @@ static int show_devs(struct seq_file *m, void *data)
962ea4f
 	int err;
962ea4f
 	u32 retval = -1;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
962ea4f
 				    &retval);
962ea4f
962ea4f
@@ -1912,6 +1918,9 @@ static int show_call(struct seq_file *m, void *data)
962ea4f
 	union acpi_object *obj;
962ea4f
 	acpi_status status;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
962ea4f
 				     1, asus->debug.method_id,
962ea4f
 				     &input, &output);
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 88156357adede0ba4060adb0934d08e75afb6e9d Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:16 +0000
962ea4f
Subject: [PATCH 23/32] ACPI: Limit access to custom_method when the kernel is
962ea4f
 locked down
962ea4f
962ea4f
custom_method effectively allows arbitrary access to system memory, making
962ea4f
it possible for an attacker to circumvent restrictions on module loading.
962ea4f
Disable it if the kernel is locked down.
962ea4f
962ea4f
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/acpi/custom_method.c | 3 +++
962ea4f
 1 file changed, 3 insertions(+)
962ea4f
962ea4f
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
962ea4f
index c68e724..e4d721c 100644
962ea4f
--- a/drivers/acpi/custom_method.c
962ea4f
+++ b/drivers/acpi/custom_method.c
962ea4f
@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
962ea4f
 	struct acpi_table_header table;
962ea4f
 	acpi_status status;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	if (!(*ppos)) {
962ea4f
 		/* parse the table header to get the table length */
962ea4f
 		if (count <= sizeof(struct acpi_table_header))
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 960205f64271826552eec6d7ba34144b1615c376 Mon Sep 17 00:00:00 2001
962ea4f
From: Josh Boyer <jwboyer@redhat.com>
962ea4f
Date: Tue, 22 Nov 2016 08:46:16 +0000
962ea4f
Subject: [PATCH 24/32] acpi: Ignore acpi_rsdp kernel param when the kernel has
962ea4f
 been locked down
962ea4f
962ea4f
This option allows userspace to pass the RSDP address to the kernel, which
962ea4f
makes it possible for a user to circumvent any restrictions imposed on
962ea4f
loading modules.  Ignore the option when the kernel is locked down.
962ea4f
962ea4f
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/acpi/osl.c | 2 +-
962ea4f
 1 file changed, 1 insertion(+), 1 deletion(-)
962ea4f
962ea4f
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
962ea4f
index 416953a..79f3d03 100644
962ea4f
--- a/drivers/acpi/osl.c
962ea4f
+++ b/drivers/acpi/osl.c
962ea4f
@@ -191,7 +191,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp);
962ea4f
 	acpi_physical_address pa = 0;
962ea4f
 
962ea4f
 #ifdef CONFIG_KEXEC
962ea4f
-	if (acpi_rsdp)
962ea4f
+	if (acpi_rsdp && !kernel_is_locked_down())
962ea4f
 		return acpi_rsdp;
962ea4f
 #endif
962ea4f
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 2f200d295a041b154f3938940c2d8aa1742f1379 Mon Sep 17 00:00:00 2001
962ea4f
From: Linn Crosetto <linn@hpe.com>
962ea4f
Date: Wed, 23 Nov 2016 13:32:27 +0000
962ea4f
Subject: [PATCH 25/32] acpi: Disable ACPI table override if the kernel is
962ea4f
 locked down
962ea4f
962ea4f
From the kernel documentation (initrd_table_override.txt):
962ea4f
962ea4f
  If the ACPI_INITRD_TABLE_OVERRIDE compile option is true, it is possible
962ea4f
  to override nearly any ACPI table provided by the BIOS with an
962ea4f
  instrumented, modified one.
962ea4f
962ea4f
When securelevel is set, the kernel should disallow any unauthenticated
962ea4f
changes to kernel space.  ACPI tables contain code invoked by the kernel,
962ea4f
so do not allow ACPI tables to be overridden if the kernel is locked down.
962ea4f
962ea4f
Signed-off-by: Linn Crosetto <linn@hpe.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/acpi/tables.c | 5 +++++
962ea4f
 1 file changed, 5 insertions(+)
962ea4f
962ea4f
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
962ea4f
index cdd56c4..c657c08 100644
962ea4f
--- a/drivers/acpi/tables.c
962ea4f
+++ b/drivers/acpi/tables.c
962ea4f
@@ -545,6 +545,11 @@ void __init acpi_table_upgrade(void)
962ea4f
 	if (table_nr == 0)
962ea4f
 		return;
962ea4f
962ea4f
+	if (kernel_is_locked_down()) {
962ea4f
+		pr_notice("kernel is locked down, ignoring table override\n");
962ea4f
+		return;
962ea4f
+	}
962ea4f
+
962ea4f
 	acpi_tables_addr =
962ea4f
 		memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
962ea4f
 				       all_tables_size, PAGE_SIZE);
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 6244dff831988f59797add76cee80c73961d5ac5 Mon Sep 17 00:00:00 2001
962ea4f
From: Linn Crosetto <linn@hpe.com>
962ea4f
Date: Wed, 23 Nov 2016 13:39:41 +0000
962ea4f
Subject: [PATCH 26/32] acpi: Disable APEI error injection if the kernel is
962ea4f
 locked down
962ea4f
962ea4f
ACPI provides an error injection mechanism, EINJ, for debugging and testing
962ea4f
the ACPI Platform Error Interface (APEI) and other RAS features.  If
962ea4f
supported by the firmware, ACPI specification 5.0 and later provide for a
962ea4f
way to specify a physical memory address to which to inject the error.
962ea4f
962ea4f
Injecting errors through EINJ can produce errors which to the platform are
962ea4f
indistinguishable from real hardware errors.  This can have undesirable
962ea4f
side-effects, such as causing the platform to mark hardware as needing
962ea4f
replacement.
962ea4f
962ea4f
While it does not provide a method to load unauthenticated privileged code,
962ea4f
the effect of these errors may persist across reboots and affect trust in
962ea4f
the underlying hardware, so disable error injection through EINJ if
962ea4f
the kernel is locked down.
962ea4f
962ea4f
Signed-off-by: Linn Crosetto <linn@hpe.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/acpi/apei/einj.c | 3 +++
962ea4f
 1 file changed, 3 insertions(+)
962ea4f
962ea4f
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
962ea4f
index eebb7e3..e4f126a 100644
962ea4f
--- a/drivers/acpi/apei/einj.c
962ea4f
+++ b/drivers/acpi/apei/einj.c
962ea4f
@@ -518,6 +518,9 @@ static int einj_error_inject(u32 type, u32 flags, u64 param1, u64 param2,
962ea4f
 	int rc;
962ea4f
 	u64 base_addr, size;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	/* If user manually set "flags", make sure it is legal */
962ea4f
 	if (flags && (flags &
962ea4f
 		~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From a17a541d1af379c3d6ff21924c212f9e2e38c1c8 Mon Sep 17 00:00:00 2001
962ea4f
From: Matthew Garrett <mjg59@coreos.com>
962ea4f
Date: Wed, 23 Nov 2016 13:41:23 +0000
962ea4f
Subject: [PATCH 27/32] Enable cold boot attack mitigation
962ea4f
962ea4f
---
962ea4f
 arch/x86/boot/compressed/eboot.c | 28 ++++++++++++++++++++++++++++
962ea4f
 1 file changed, 28 insertions(+)
962ea4f
962ea4f
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
962ea4f
index 5b151c2..5093a76 100644
962ea4f
--- a/arch/x86/boot/compressed/eboot.c
962ea4f
+++ b/arch/x86/boot/compressed/eboot.c
962ea4f
@@ -774,6 +774,31 @@ void setup_graphics(struct boot_params *boot_params)
962ea4f
 	}
962ea4f
 }
962ea4f
962ea4f
+#define MEMORY_ONLY_RESET_CONTROL_GUID \
962ea4f
+	EFI_GUID (0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
962ea4f
+
962ea4f
+static void enable_reset_attack_mitigation(void)
962ea4f
+{
962ea4f
+	static const efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
962ea4f
+	static const efi_char16_t MemoryOverwriteRequestControl_name[] = {
962ea4f
+		'M', 'e', 'm', 'o', 'r', 'y',
962ea4f
+		'O', 'v', 'e', 'r', 'w', 'r', 'i', 't', 'e',
962ea4f
+		'R', 'e', 'q', 'u', 'e', 's', 't',
962ea4f
+		'C', 'o', 'n', 't', 'r', 'o', 'l',
962ea4f
+		0
962ea4f
+	};
962ea4f
+	u8 val = 1;
962ea4f
+
962ea4f
+	/* Ignore the return value here - there's not really a lot we can do */
962ea4f
+	efi_call_runtime(set_variable,
962ea4f
+			(efi_char16_t *)MemoryOverwriteRequestControl_name,
962ea4f
+			(efi_guid_t *)&var_guid,
962ea4f
+			EFI_VARIABLE_NON_VOLATILE |
962ea4f
+			EFI_VARIABLE_BOOTSERVICE_ACCESS |
962ea4f
+			EFI_VARIABLE_RUNTIME_ACCESS,
962ea4f
+			sizeof(val), val);
962ea4f
+}
962ea4f
+
962ea4f
 /*
962ea4f
  * Because the x86 boot code expects to be passed a boot_params we
962ea4f
  * need to create one ourselves (usually the bootloader would create
962ea4f
@@ -1158,6 +1183,9 @@ struct boot_params *efi_main(struct efi_config *c,
962ea4f
 	else
962ea4f
 		setup_boot_services32(efi_early);
962ea4f
962ea4f
+	/* Ask the firmware to clear memory if we don't have a clean shutdown */
962ea4f
+	enable_reset_attack_mitigation();
962ea4f
+
cd3596b
 	/*
cd3596b
 	 * If the boot loader gave us a value for secure_boot then we use that,
cd3596b
 	 * otherwise we ask the BIOS.
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From c9c34942d873f7a09b9c7211bda3063354ff5706 Mon Sep 17 00:00:00 2001
962ea4f
From: "Lee, Chun-Yi" <jlee@suse.com>
962ea4f
Date: Wed, 23 Nov 2016 13:52:16 +0000
962ea4f
Subject: [PATCH 28/32] bpf: Restrict kernel image access functions when the
962ea4f
 kernel is locked down
962ea4f
962ea4f
There are some bpf functions can be used to read kernel memory:
962ea4f
bpf_probe_read, bpf_probe_write_user and bpf_trace_printk.  These allow
962ea4f
private keys in kernel memory (e.g. the hibernation image signing key) to
962ea4f
be read by an eBPF program.  Prohibit those functions when the kernel is
962ea4f
locked down.
962ea4f
962ea4f
Signed-off-by: Lee, Chun-Yi <jlee@suse.com>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 kernel/trace/bpf_trace.c | 11 +++++++++++
962ea4f
 1 file changed, 11 insertions(+)
962ea4f
962ea4f
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
962ea4f
index 5dcb992..474e001 100644
962ea4f
--- a/kernel/trace/bpf_trace.c
962ea4f
+++ b/kernel/trace/bpf_trace.c
962ea4f
@@ -65,6 +65,11 @@ BPF_CALL_3(bpf_probe_read, void *, dst, u32, size, const void *, unsafe_ptr)
962ea4f
 {
962ea4f
 	int ret;
962ea4f
962ea4f
+	if (kernel_is_locked_down()) {
962ea4f
+		memset(dst, 0, size);
962ea4f
+		return -EPERM;
962ea4f
+	}
962ea4f
+
962ea4f
 	ret = probe_kernel_read(dst, unsafe_ptr, size);
962ea4f
 	if (unlikely(ret < 0))
962ea4f
 		memset(dst, 0, size);
962ea4f
@@ -84,6 +89,9 @@ static const struct bpf_func_proto bpf_probe_read_proto = {
962ea4f
 BPF_CALL_3(bpf_probe_write_user, void *, unsafe_ptr, const void *, src,
962ea4f
 	   u32, size)
962ea4f
 {
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return -EPERM;
962ea4f
+
962ea4f
 	/*
962ea4f
 	 * Ensure we're in user context which is safe for the helper to
962ea4f
 	 * run. This helper has no business in a kthread.
962ea4f
@@ -143,6 +151,9 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1,
962ea4f
 	if (fmt[--fmt_size] != 0)
962ea4f
 		return -EINVAL;
962ea4f
962ea4f
+	if (kernel_is_locked_down())
962ea4f
+		return __trace_printk(1, fmt, 0, 0, 0);
962ea4f
+
962ea4f
 	/* check format string for allowed specifiers */
962ea4f
 	for (i = 0; i < fmt_size; i++) {
962ea4f
 		if ((!isprint(fmt[i]) && !isspace(fmt[i])) || !isascii(fmt[i]))
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 04485aa7865dc340f38e32ad29793c625167acf3 Mon Sep 17 00:00:00 2001
962ea4f
From: David Howells <dhowells@redhat.com>
962ea4f
Date: Tue, 22 Nov 2016 10:10:34 +0000
962ea4f
Subject: [PATCH 29/32] scsi: Lock down the eata driver
962ea4f
962ea4f
When the kernel is running in secure boot mode, we lock down the kernel to
962ea4f
prevent userspace from modifying the running kernel image.  Whilst this
962ea4f
includes prohibiting access to things like /dev/mem, it must also prevent
962ea4f
access by means of configuring driver modules in such a way as to cause a
962ea4f
device to access or modify the kernel image.
962ea4f
962ea4f
The eata driver takes a single string parameter that contains a slew of
962ea4f
settings, including hardware resource configuration.  Prohibit use of the
962ea4f
parameter if the kernel is locked down.
962ea4f
962ea4f
Suggested-by: One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
cc: Dario Ballabio <ballabio_dario@emc.com>
962ea4f
cc: "James E.J. Bottomley" <jejb@linux.vnet.ibm.com>
962ea4f
cc: "Martin K. Petersen" <martin.petersen@oracle.com>
962ea4f
cc: linux-scsi@vger.kernel.org
962ea4f
---
962ea4f
 drivers/scsi/eata.c | 7 ++++++-
962ea4f
 1 file changed, 6 insertions(+), 1 deletion(-)
962ea4f
962ea4f
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
962ea4f
index 227dd2c..5c036d1 100644
962ea4f
--- a/drivers/scsi/eata.c
962ea4f
+++ b/drivers/scsi/eata.c
962ea4f
@@ -1552,8 +1552,13 @@ static int eata2x_detect(struct scsi_host_template *tpnt)
962ea4f
962ea4f
 	tpnt->proc_name = "eata2x";
962ea4f
962ea4f
-	if (strlen(boot_options))
962ea4f
+	if (strlen(boot_options)) {
962ea4f
+		if (kernel_is_locked_down()) {
962ea4f
+			pr_err("Command line-specified device addresses, irqs and dma channels are not permitted when the kernel is locked down\n");
962ea4f
+			return -EPERM;
962ea4f
+		}
962ea4f
 		option_setup(boot_options);
962ea4f
+	}
962ea4f
962ea4f
 #if defined(MODULE)
962ea4f
 	/* io_port could have been modified when loading as a module */
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From b1e8f012b7b17e0146f8e63de51f6f45819c859e Mon Sep 17 00:00:00 2001
962ea4f
From: David Howells <dhowells@redhat.com>
962ea4f
Date: Fri, 25 Nov 2016 14:37:45 +0000
962ea4f
Subject: [PATCH 30/32] Prohibit PCMCIA CIS storage when the kernel is locked
962ea4f
 down
962ea4f
962ea4f
Prohibit replacement of the PCMCIA Card Information Structure when the
962ea4f
kernel is locked down.
962ea4f
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/pcmcia/cistpl.c | 5 +++++
962ea4f
 1 file changed, 5 insertions(+)
962ea4f
962ea4f
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
962ea4f
index 55ef7d1..193e4f7 100644
962ea4f
--- a/drivers/pcmcia/cistpl.c
962ea4f
+++ b/drivers/pcmcia/cistpl.c
962ea4f
@@ -1578,6 +1578,11 @@ static ssize_t pccard_store_cis(struct file *filp, struct kobject *kobj,
962ea4f
 	struct pcmcia_socket *s;
962ea4f
 	int error;
962ea4f
962ea4f
+	if (kernel_is_locked_down()) {
962ea4f
+		pr_err("Direct CIS storage isn't permitted when the kernel is locked down\n");
962ea4f
+		return -EPERM;
962ea4f
+	}
962ea4f
+
962ea4f
 	s = to_socket(container_of(kobj, struct device, kobj));
962ea4f
962ea4f
 	if (off)
962ea4f
-- 
962ea4f
2.9.3
962ea4f
962ea4f
From 66d9c09b9427719e3c6a34132e9ca0724cb1e3a8 Mon Sep 17 00:00:00 2001
962ea4f
From: David Howells <dhowells@redhat.com>
962ea4f
Date: Wed, 7 Dec 2016 10:28:39 +0000
962ea4f
Subject: [PATCH 31/32] Lock down TIOCSSERIAL
962ea4f
962ea4f
Lock down TIOCSSERIAL as that can be used to change the ioport and irq
962ea4f
settings on a serial port.  This only appears to be an issue for the serial
962ea4f
drivers that use the core serial code.  All other drivers seem to either
962ea4f
ignore attempts to change port/irq or give an error.
962ea4f
962ea4f
Reported-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
962ea4f
Signed-off-by: David Howells <dhowells@redhat.com>
962ea4f
---
962ea4f
 drivers/tty/serial/serial_core.c | 6 ++++++
962ea4f
 1 file changed, 6 insertions(+)
962ea4f
962ea4f
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
962ea4f
index f2303f3..f2c07fa 100644
962ea4f
--- a/drivers/tty/serial/serial_core.c
962ea4f
+++ b/drivers/tty/serial/serial_core.c
962ea4f
@@ -819,6 +819,12 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
962ea4f
 	new_flags = new_info->flags;
962ea4f
 	old_custom_divisor = uport->custom_divisor;
962ea4f
962ea4f
+	if ((change_port || change_irq) && kernel_is_locked_down()) {
962ea4f
+		pr_err("Using TIOCSSERIAL to change device addresses, irqs and dma channels is not permitted when the kernel is locked down\n");
962ea4f
+		retval = -EPERM;
962ea4f
+		goto exit;
962ea4f
+	}
962ea4f
+
962ea4f
 	if (!capable(CAP_SYS_ADMIN)) {
962ea4f
 		retval = -EPERM;
962ea4f
 		if (change_irq || change_port ||
962ea4f
-- 
962ea4f
2.9.3