76b66ee
From 8dea807503a1ba88d9e27595daae7f86ec968711 Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Fri, 9 Aug 2013 17:58:15 -0400
76b66ee
Subject: [PATCH 01/14] Add secure_modules() call
fb10477
fb10477
Provide a single call to allow kernel code to determine whether the system
fb10477
has been configured to either disable module loading entirely or to load
fb10477
only modules signed with a trusted key.
fb10477
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
fb10477
 include/linux/module.h |  7 +++++++
fb10477
 kernel/module.c        | 10 ++++++++++
fb10477
 2 files changed, 17 insertions(+)
fb10477
fb10477
diff --git a/include/linux/module.h b/include/linux/module.h
fb10477
index 46f1ea0..0c266b2 100644
fb10477
--- a/include/linux/module.h
fb10477
+++ b/include/linux/module.h
fb10477
@@ -509,6 +509,8 @@ int unregister_module_notifier(struct notifier_block * nb);
fb10477
 
fb10477
 extern void print_modules(void);
fb10477
 
fb10477
+extern bool secure_modules(void);
fb10477
+
fb10477
 #else /* !CONFIG_MODULES... */
fb10477
 
fb10477
 /* Given an address, look for it in the exception tables. */
fb10477
@@ -619,6 +621,11 @@ static inline int unregister_module_notifier(struct notifier_block * nb)
fb10477
 static inline void print_modules(void)
fb10477
 {
fb10477
 }
fb10477
+
fb10477
+static inline bool secure_modules(void)
fb10477
+{
fb10477
+	return false;
fb10477
+}
fb10477
 #endif /* CONFIG_MODULES */
fb10477
 
fb10477
 #ifdef CONFIG_SYSFS
fb10477
diff --git a/kernel/module.c b/kernel/module.c
76b66ee
index 2069158..0e94acf 100644
fb10477
--- a/kernel/module.c
fb10477
+++ b/kernel/module.c
fb10477
@@ -3852,3 +3852,13 @@ void module_layout(struct module *mod,
fb10477
 }
fb10477
 EXPORT_SYMBOL(module_layout);
fb10477
 #endif
fb10477
+
fb10477
+bool secure_modules(void)
fb10477
+{
fb10477
+#ifdef CONFIG_MODULE_SIG
fb10477
+	return (sig_enforce || modules_disabled);
fb10477
+#else
fb10477
+	return modules_disabled;
fb10477
+#endif
fb10477
+}
76b66ee
+EXPORT_SYMBOL(secure_modules);
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From 9b7b3f6283bf784e4ea1c34e52646b12971b2823 Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Thu, 8 Mar 2012 10:10:38 -0500
76b66ee
Subject: [PATCH 02/14] PCI: Lock down BAR access when module security is
fb10477
 enabled
fb10477
fb10477
Any hardware that can potentially generate DMA has to be locked down from
fb10477
userspace in order to avoid it being possible for an attacker to modify
fb10477
kernel code, allowing them to circumvent disabled module loading or module
fb10477
signing. Default to paranoid - in future we can potentially relax this for
fb10477
sufficiently IOMMU-isolated devices.
fb10477
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
fb10477
 drivers/pci/pci-sysfs.c | 10 ++++++++++
fb10477
 drivers/pci/proc.c      |  8 +++++++-
fb10477
 drivers/pci/syscall.c   |  3 ++-
fb10477
 3 files changed, 19 insertions(+), 2 deletions(-)
fb10477
fb10477
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
fb10477
index c0dbe1f..cd4e35f 100644
fb10477
--- a/drivers/pci/pci-sysfs.c
fb10477
+++ b/drivers/pci/pci-sysfs.c
fb10477
@@ -29,6 +29,7 @@
fb10477
 #include <linux/slab.h>
fb10477
 #include <linux/vgaarb.h>
fb10477
 #include <linux/pm_runtime.h>
fb10477
+#include <linux/module.h>
fb10477
 #include "pci.h"
fb10477
 
fb10477
 static int sysfs_initialized;	/* = 0 */
fb10477
@@ -624,6 +625,9 @@ pci_write_config(struct file* filp, struct kobject *kobj,
fb10477
 	loff_t init_off = off;
fb10477
 	u8 *data = (u8*) buf;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	if (off > dev->cfg_size)
fb10477
 		return 0;
fb10477
 	if (off + count > dev->cfg_size) {
fb10477
@@ -930,6 +934,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
fb10477
 	resource_size_t start, end;
fb10477
 	int i;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	for (i = 0; i < PCI_ROM_RESOURCE; i++)
fb10477
 		if (res == &pdev->resource[i])
fb10477
 			break;
fb10477
@@ -1037,6 +1044,9 @@ pci_write_resource_io(struct file *filp, struct kobject *kobj,
fb10477
 		      struct bin_attribute *attr, char *buf,
fb10477
 		      loff_t off, size_t count)
fb10477
 {
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
fb10477
 }
fb10477
 
fb10477
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
fb10477
index cdc7836..e3d498b 100644
fb10477
--- a/drivers/pci/proc.c
fb10477
+++ b/drivers/pci/proc.c
fb10477
@@ -117,6 +117,9 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
fb10477
 	int size = dev->cfg_size;
fb10477
 	int cnt;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	if (pos >= size)
fb10477
 		return 0;
fb10477
 	if (nbytes >= size)
fb10477
@@ -196,6 +199,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
fb10477
 #endif /* HAVE_PCI_MMAP */
fb10477
 	int ret = 0;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	switch (cmd) {
fb10477
 	case PCIIOC_CONTROLLER:
fb10477
 		ret = pci_domain_nr(dev->bus);
fb10477
@@ -234,7 +240,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
fb10477
 	struct pci_filp_private *fpriv = file->private_data;
fb10477
 	int i, ret;
fb10477
 
fb10477
-	if (!capable(CAP_SYS_RAWIO))
fb10477
+	if (!capable(CAP_SYS_RAWIO) || secure_modules())
fb10477
 		return -EPERM;
fb10477
 
fb10477
 	/* Make sure the caller is mapping a real resource for this device */
fb10477
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
fb10477
index e1c1ec5..bffbf71 100644
fb10477
--- a/drivers/pci/syscall.c
fb10477
+++ b/drivers/pci/syscall.c
fb10477
@@ -10,6 +10,7 @@
fb10477
 #include <linux/errno.h>
fb10477
 #include <linux/pci.h>
fb10477
 #include <linux/syscalls.h>
fb10477
+#include <linux/module.h>
fb10477
 #include <asm/uaccess.h>
fb10477
 #include "pci.h"
fb10477
 
fb10477
@@ -92,7 +93,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
fb10477
 	u32 dword;
fb10477
 	int err = 0;
fb10477
 
fb10477
-	if (!capable(CAP_SYS_ADMIN))
fb10477
+	if (!capable(CAP_SYS_ADMIN) || secure_modules())
fb10477
 		return -EPERM;
fb10477
 
fb10477
 	dev = pci_get_bus_and_slot(bus, dfn);
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From aac2425a2664c09c2a369e1eec6e7a5bc2713cb1 Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Thu, 8 Mar 2012 10:35:59 -0500
76b66ee
Subject: [PATCH 03/14] x86: Lock down IO port access when module security is
fb10477
 enabled
fb10477
fb10477
IO port access would permit users to gain access to PCI configuration
fb10477
registers, which in turn (on a lot of hardware) give access to MMIO register
fb10477
space. This would potentially permit root to trigger arbitrary DMA, so lock
fb10477
it down by default.
fb10477
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
fb10477
 arch/x86/kernel/ioport.c | 5 +++--
fb10477
 drivers/char/mem.c       | 4 ++++
fb10477
 2 files changed, 7 insertions(+), 2 deletions(-)
fb10477
fb10477
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
fb10477
index 4ddaf66..00b4403 100644
fb10477
--- a/arch/x86/kernel/ioport.c
fb10477
+++ b/arch/x86/kernel/ioport.c
fb10477
@@ -15,6 +15,7 @@
fb10477
 #include <linux/thread_info.h>
fb10477
 #include <linux/syscalls.h>
fb10477
 #include <linux/bitmap.h>
fb10477
+#include <linux/module.h>
fb10477
 #include <asm/syscalls.h>
fb10477
 
fb10477
 /*
fb10477
@@ -28,7 +29,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
fb10477
 
fb10477
 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
fb10477
 		return -EINVAL;
fb10477
-	if (turn_on && !capable(CAP_SYS_RAWIO))
fb10477
+	if (turn_on && (!capable(CAP_SYS_RAWIO) || secure_modules()))
fb10477
 		return -EPERM;
fb10477
 
fb10477
 	/*
fb10477
@@ -103,7 +104,7 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
fb10477
 		return -EINVAL;
fb10477
 	/* Trying to gain more privileges? */
fb10477
 	if (level > old) {
fb10477
-		if (!capable(CAP_SYS_RAWIO))
fb10477
+		if (!capable(CAP_SYS_RAWIO) || secure_modules())
fb10477
 			return -EPERM;
fb10477
 	}
fb10477
 	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
fb10477
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
fb10477
index f895a8c..1af8664 100644
fb10477
--- a/drivers/char/mem.c
fb10477
+++ b/drivers/char/mem.c
fb10477
@@ -28,6 +28,7 @@
fb10477
 #include <linux/export.h>
fb10477
 #include <linux/io.h>
fb10477
 #include <linux/aio.h>
fb10477
+#include <linux/module.h>
fb10477
 
fb10477
 #include <asm/uaccess.h>
fb10477
 
fb10477
@@ -563,6 +564,9 @@ static ssize_t write_port(struct file *file, const char __user *buf,
fb10477
 	unsigned long i = *ppos;
fb10477
 	const char __user *tmp = buf;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	if (!access_ok(VERIFY_READ, buf, count))
fb10477
 		return -EFAULT;
fb10477
 	while (count-- > 0 && i < 65536) {
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From e7f9789c7eedf291972666befee726ff8e7126f6 Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Fri, 9 Mar 2012 08:39:37 -0500
76b66ee
Subject: [PATCH 04/14] ACPI: Limit access to custom_method
fb10477
fb10477
custom_method effectively allows arbitrary access to system memory, making
fb10477
it possible for an attacker to circumvent restrictions on module loading.
fb10477
Disable it if any such restrictions have been enabled.
fb10477
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
76b66ee
 drivers/acpi/custom_method.c | 3 +++
76b66ee
 1 file changed, 3 insertions(+)
fb10477
fb10477
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
76b66ee
index 12b62f2..50647b3 100644
fb10477
--- a/drivers/acpi/custom_method.c
fb10477
+++ b/drivers/acpi/custom_method.c
76b66ee
@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
fb10477
 	struct acpi_table_header table;
fb10477
 	acpi_status status;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	if (!(*ppos)) {
fb10477
 		/* parse the table header to get the table length */
fb10477
 		if (count <= sizeof(struct acpi_table_header))
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From d81cd6628c821d47bd086354cbc57b1474f3c1a8 Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Fri, 9 Mar 2012 08:46:50 -0500
76b66ee
Subject: [PATCH 05/14] asus-wmi: Restrict debugfs interface when module
fb10477
 loading is restricted
fb10477
fb10477
We have no way of validating what all of the Asus WMI methods do on a
fb10477
given machine, and there's a risk that some will allow hardware state to
fb10477
be manipulated in such a way that arbitrary code can be executed in the
fb10477
kernel, circumventing module loading restrictions. Prevent that if any of
fb10477
these features are enabled.
fb10477
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
fb10477
 drivers/platform/x86/asus-wmi.c | 9 +++++++++
fb10477
 1 file changed, 9 insertions(+)
fb10477
fb10477
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
fb10477
index 19c313b..db18ef66 100644
fb10477
--- a/drivers/platform/x86/asus-wmi.c
fb10477
+++ b/drivers/platform/x86/asus-wmi.c
fb10477
@@ -1618,6 +1618,9 @@ static int show_dsts(struct seq_file *m, void *data)
fb10477
 	int err;
fb10477
 	u32 retval = -1;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
fb10477
 
fb10477
 	if (err < 0)
fb10477
@@ -1634,6 +1637,9 @@ static int show_devs(struct seq_file *m, void *data)
fb10477
 	int err;
fb10477
 	u32 retval = -1;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
fb10477
 				    &retval);
fb10477
 
fb10477
@@ -1658,6 +1664,9 @@ static int show_call(struct seq_file *m, void *data)
fb10477
 	union acpi_object *obj;
fb10477
 	acpi_status status;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
fb10477
 				     1, asus->debug.method_id,
fb10477
 				     &input, &output);
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From df75e984729ef50bb691b4d15472529fcd81580b Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Fri, 9 Mar 2012 09:28:15 -0500
76b66ee
Subject: [PATCH 06/14] Restrict /dev/mem and /dev/kmem when module loading is
fb10477
 restricted
fb10477
fb10477
Allowing users to write to address space makes it possible for the kernel
fb10477
to be subverted, avoiding module loading restrictions. Prevent this when
fb10477
any restrictions have been imposed on loading modules.
fb10477
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
fb10477
 drivers/char/mem.c | 6 ++++++
fb10477
 1 file changed, 6 insertions(+)
fb10477
fb10477
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
fb10477
index 1af8664..61406c8 100644
fb10477
--- a/drivers/char/mem.c
fb10477
+++ b/drivers/char/mem.c
fb10477
@@ -159,6 +159,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
fb10477
 	unsigned long copied;
fb10477
 	void *ptr;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	if (!valid_phys_addr_range(p, count))
fb10477
 		return -EFAULT;
fb10477
 
fb10477
@@ -497,6 +500,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
fb10477
 	char *kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
fb10477
 	int err = 0;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	if (p < (unsigned long) high_memory) {
fb10477
 		unsigned long to_write = min_t(unsigned long, count,
fb10477
 					       (unsigned long)high_memory - p);
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From 78955913cc46cc5e5c7f2c71c1b07a5c18e06456 Mon Sep 17 00:00:00 2001
fb10477
From: Josh Boyer <jwboyer@redhat.com>
76b66ee
Date: Mon, 25 Jun 2012 19:57:30 -0400
76b66ee
Subject: [PATCH 07/14] acpi: Ignore acpi_rsdp kernel parameter when module
fb10477
 loading is restricted
fb10477
fb10477
This option allows userspace to pass the RSDP address to the kernel, which
fb10477
makes it possible for a user to circumvent any restrictions imposed on
fb10477
loading modules. Disable it in that case.
fb10477
fb10477
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
fb10477
---
fb10477
 drivers/acpi/osl.c | 3 ++-
fb10477
 1 file changed, 2 insertions(+), 1 deletion(-)
fb10477
fb10477
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
fb10477
index 6ab2c35..e4c4410 100644
fb10477
--- a/drivers/acpi/osl.c
fb10477
+++ b/drivers/acpi/osl.c
fb10477
@@ -45,6 +45,7 @@
fb10477
 #include <linux/list.h>
fb10477
 #include <linux/jiffies.h>
fb10477
 #include <linux/semaphore.h>
fb10477
+#include <linux/module.h>
fb10477
 
fb10477
 #include <asm/io.h>
fb10477
 #include <asm/uaccess.h>
fb10477
@@ -245,7 +246,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp);
fb10477
 acpi_physical_address __init acpi_os_get_root_pointer(void)
fb10477
 {
fb10477
 #ifdef CONFIG_KEXEC
fb10477
-	if (acpi_rsdp)
fb10477
+	if (acpi_rsdp && !secure_modules())
fb10477
 		return acpi_rsdp;
fb10477
 #endif
fb10477
 
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From 23aae9143fbece326b3a26bf5ba48956c99cabe4 Mon Sep 17 00:00:00 2001
76b66ee
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Fri, 9 Aug 2013 03:33:56 -0400
76b66ee
Subject: [PATCH 08/14] kexec: Disable at runtime if the kernel enforces module
76b66ee
 loading restrictions
76b66ee
76b66ee
kexec permits the loading and execution of arbitrary code in ring 0, which
76b66ee
is something that module signing enforcement is meant to prevent. It makes
76b66ee
sense to disable kexec in this situation.
76b66ee
76b66ee
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
---
76b66ee
 kernel/kexec.c | 8 ++++++++
76b66ee
 1 file changed, 8 insertions(+)
76b66ee
76b66ee
diff --git a/kernel/kexec.c b/kernel/kexec.c
76b66ee
index 59f7b55..3e2b63a 100644
76b66ee
--- a/kernel/kexec.c
76b66ee
+++ b/kernel/kexec.c
76b66ee
@@ -32,6 +32,7 @@
76b66ee
 #include <linux/vmalloc.h>
76b66ee
 #include <linux/swap.h>
76b66ee
 #include <linux/syscore_ops.h>
76b66ee
+#include <linux/module.h>
76b66ee
 
76b66ee
 #include <asm/page.h>
76b66ee
 #include <asm/uaccess.h>
76b66ee
@@ -943,6 +944,13 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
76b66ee
 		return -EPERM;
76b66ee
 
76b66ee
 	/*
76b66ee
+	 * kexec can be used to circumvent module loading restrictions, so
76b66ee
+	 * prevent loading in that case
76b66ee
+	 */
76b66ee
+	if (secure_modules())
76b66ee
+		return -EPERM;
76b66ee
+
76b66ee
+	/*
76b66ee
 	 * Verify we have a legal set of flags
76b66ee
 	 * This leaves us room for future extensions.
76b66ee
 	 */
76b66ee
-- 
76b66ee
1.8.3.1
76b66ee
76b66ee
76b66ee
From 218cd49aa2d6a085c5c4edc0396200864f0b54ad Mon Sep 17 00:00:00 2001
76b66ee
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Tue, 3 Sep 2013 11:23:29 -0400
76b66ee
Subject: [PATCH 09/14] uswsusp: Disable when module loading is restricted
76b66ee
76b66ee
uswsusp allows a user process to dump and then restore kernel state, which
76b66ee
makes it possible to avoid module loading restrictions. Prevent this when
76b66ee
any restrictions have been imposed on loading modules.
76b66ee
76b66ee
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
---
76b66ee
 kernel/power/user.c | 4 ++++
76b66ee
 1 file changed, 4 insertions(+)
76b66ee
76b66ee
diff --git a/kernel/power/user.c b/kernel/power/user.c
76b66ee
index 4ed81e7..15cb72f 100644
76b66ee
--- a/kernel/power/user.c
76b66ee
+++ b/kernel/power/user.c
76b66ee
@@ -24,6 +24,7 @@
76b66ee
 #include <linux/console.h>
76b66ee
 #include <linux/cpu.h>
76b66ee
 #include <linux/freezer.h>
76b66ee
+#include <linux/module.h>
76b66ee
 
76b66ee
 #include <asm/uaccess.h>
76b66ee
 
76b66ee
@@ -48,6 +49,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
76b66ee
 	struct snapshot_data *data;
76b66ee
 	int error;
76b66ee
 
76b66ee
+	if (secure_modules())
76b66ee
+		return -EPERM;
76b66ee
+
76b66ee
 	lock_system_sleep();
76b66ee
 
76b66ee
 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
76b66ee
-- 
76b66ee
1.8.3.1
76b66ee
76b66ee
76b66ee
From beeaac053d4ae57dc65be1da8b46e5d4bc6542b8 Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Fri, 8 Feb 2013 11:12:13 -0800
76b66ee
Subject: [PATCH 10/14] x86: Restrict MSR access when module loading is
fb10477
 restricted
fb10477
fb10477
Writing to MSRs should not be allowed if module loading is restricted,
fb10477
since it could lead to execution of arbitrary code in kernel mode. Based
fb10477
on a patch by Kees Cook.
fb10477
fb10477
Cc: Kees Cook <keescook@chromium.org>
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
fb10477
 arch/x86/kernel/msr.c | 7 +++++++
fb10477
 1 file changed, 7 insertions(+)
fb10477
fb10477
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
fb10477
index 88458fa..d08f7e3 100644
fb10477
--- a/arch/x86/kernel/msr.c
fb10477
+++ b/arch/x86/kernel/msr.c
fb10477
@@ -103,6 +103,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
fb10477
 	int err = 0;
fb10477
 	ssize_t bytes = 0;
fb10477
 
fb10477
+	if (secure_modules())
fb10477
+		return -EPERM;
fb10477
+
fb10477
 	if (count % 8)
fb10477
 		return -EINVAL;	/* Invalid chunk size */
fb10477
 
fb10477
@@ -150,6 +153,10 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
fb10477
 			err = -EBADF;
fb10477
 			break;
fb10477
 		}
fb10477
+		if (secure_modules()) {
fb10477
+			err = -EPERM;
fb10477
+			break;
fb10477
+		}
fb10477
 		if (copy_from_user(&regs, uregs, sizeof regs)) {
fb10477
 			err = -EFAULT;
fb10477
 			break;
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From b4331711c52aff0a6a9cef0f4b52fe261874d6f2 Mon Sep 17 00:00:00 2001
fb10477
From: Matthew Garrett <matthew.garrett@nebula.com>
76b66ee
Date: Fri, 9 Aug 2013 18:36:30 -0400
76b66ee
Subject: [PATCH 11/14] Add option to automatically enforce module signatures
fb10477
 when in Secure Boot mode
fb10477
fb10477
UEFI Secure Boot provides a mechanism for ensuring that the firmware will
fb10477
only load signed bootloaders and kernels. Certain use cases may also
fb10477
require that all kernel modules also be signed. Add a configuration option
fb10477
that enforces this automatically when enabled.
fb10477
fb10477
Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
fb10477
---
76b66ee
 Documentation/x86/zero-page.txt       |  2 ++
76b66ee
 arch/x86/Kconfig                      | 10 ++++++++++
76b66ee
 arch/x86/boot/compressed/eboot.c      | 36 +++++++++++++++++++++++++++++++++++
76b66ee
 arch/x86/include/uapi/asm/bootparam.h |  3 ++-
76b66ee
 arch/x86/kernel/setup.c               |  6 ++++++
76b66ee
 include/linux/module.h                |  6 ++++++
76b66ee
 kernel/module.c                       |  7 +++++++
76b66ee
 7 files changed, 69 insertions(+), 1 deletion(-)
fb10477
fb10477
diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
fb10477
index 199f453..ec38acf 100644
fb10477
--- a/Documentation/x86/zero-page.txt
fb10477
+++ b/Documentation/x86/zero-page.txt
fb10477
@@ -30,6 +30,8 @@ Offset	Proto	Name		Meaning
fb10477
 1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
fb10477
 1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
fb10477
 				(below)
fb10477
+1EB/001	ALL     kbd_status      Numlock is enabled
fb10477
+1EC/001	ALL     secure_boot	Secure boot is enabled in the firmware
fb10477
 1EF/001	ALL	sentinel	Used to detect broken bootloaders
fb10477
 290/040	ALL	edd_mbr_sig_buffer EDD MBR signatures
fb10477
 2D0/A00	ALL	e820_map	E820 memory map table
fb10477
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
fb10477
index b32ebf9..6a6c19b 100644
fb10477
--- a/arch/x86/Kconfig
fb10477
+++ b/arch/x86/Kconfig
fb10477
@@ -1581,6 +1581,16 @@ config EFI_STUB
fb10477
 
fb10477
 	  See Documentation/x86/efi-stub.txt for more information.
fb10477
 
fb10477
+config EFI_SECURE_BOOT_SIG_ENFORCE
fb10477
+        def_bool n
fb10477
+	prompt "Force module signing when UEFI Secure Boot is enabled"
fb10477
+	---help---
fb10477
+	  UEFI Secure Boot provides a mechanism for ensuring that the
fb10477
+	  firmware will only load signed bootloaders and kernels. Certain
fb10477
+	  use cases may also require that all kernel modules also be signed.
fb10477
+	  Say Y here to automatically enable module signature enforcement
fb10477
+	  when a system boots with UEFI Secure Boot enabled.
fb10477
+
fb10477
 config SECCOMP
fb10477
 	def_bool y
fb10477
 	prompt "Enable seccomp to safely compute untrusted bytecode"
fb10477
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
76b66ee
index b7388a4..53bfe4f 100644
fb10477
--- a/arch/x86/boot/compressed/eboot.c
fb10477
+++ b/arch/x86/boot/compressed/eboot.c
76b66ee
@@ -12,6 +12,7 @@
76b66ee
 #include <asm/efi.h>
76b66ee
 #include <asm/setup.h>
76b66ee
 #include <asm/desc.h>
76b66ee
+#include <asm/bootparam_utils.h>
76b66ee
 
76b66ee
 #undef memcpy			/* Use memcpy from misc.c */
76b66ee
 
76b66ee
@@ -861,6 +862,37 @@ fail:
fb10477
 	return status;
fb10477
 }
fb10477
 
76b66ee
+static int get_secure_boot(void)
fb10477
+{
fb10477
+	u8 sb, setup;
fb10477
+	unsigned long datasize = sizeof(sb);
fb10477
+	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
fb10477
+	efi_status_t status;
fb10477
+
fb10477
+	status = efi_call_phys5(sys_table->runtime->get_variable,
fb10477
+				L"SecureBoot", &var_guid, NULL, &datasize, &sb);
fb10477
+
fb10477
+	if (status != EFI_SUCCESS)
fb10477
+		return 0;
fb10477
+
fb10477
+	if (sb == 0)
fb10477
+		return 0;
fb10477
+
fb10477
+
fb10477
+	status = efi_call_phys5(sys_table->runtime->get_variable,
fb10477
+				L"SetupMode", &var_guid, NULL, &datasize,
fb10477
+				&setup);
fb10477
+
fb10477
+	if (status != EFI_SUCCESS)
fb10477
+		return 0;
fb10477
+
fb10477
+	if (setup == 1)
fb10477
+		return 0;
fb10477
+
fb10477
+	return 1;
fb10477
+}
fb10477
+
fb10477
+
fb10477
 /*
fb10477
  * Because the x86 boot code expects to be passed a boot_params we
fb10477
  * need to create one ourselves (usually the bootloader would create
76b66ee
@@ -1169,6 +1201,10 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
fb10477
 	if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
fb10477
 		goto fail;
fb10477
 
76b66ee
+	sanitize_boot_params(boot_params);
76b66ee
+
76b66ee
+	boot_params->secure_boot = get_secure_boot();
fb10477
+
fb10477
 	setup_graphics(boot_params);
fb10477
 
fb10477
 	setup_efi_pci(boot_params);
fb10477
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
76b66ee
index c15ddaf..85d7685 100644
fb10477
--- a/arch/x86/include/uapi/asm/bootparam.h
fb10477
+++ b/arch/x86/include/uapi/asm/bootparam.h
fb10477
@@ -131,7 +131,8 @@ struct boot_params {
fb10477
 	__u8  eddbuf_entries;				/* 0x1e9 */
fb10477
 	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
fb10477
 	__u8  kbd_status;				/* 0x1eb */
fb10477
-	__u8  _pad5[3];					/* 0x1ec */
fb10477
+	__u8  secure_boot;				/* 0x1ec */
76b66ee
+	__u8  _pad5[2];					/* 0x1ed */
fb10477
 	/*
fb10477
 	 * The sentinel is set to a nonzero value (0xff) in header.S.
fb10477
 	 *
fb10477
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
fb10477
index f8ec578..deeb7bc 100644
fb10477
--- a/arch/x86/kernel/setup.c
fb10477
+++ b/arch/x86/kernel/setup.c
fb10477
@@ -1129,6 +1129,12 @@ void __init setup_arch(char **cmdline_p)
fb10477
 
fb10477
 	io_delay_init();
fb10477
 
fb10477
+#ifdef CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE
fb10477
+	if (boot_params.secure_boot) {
fb10477
+		enforce_signed_modules();
fb10477
+	}
fb10477
+#endif
fb10477
+
fb10477
 	/*
fb10477
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
fb10477
 	 */
fb10477
diff --git a/include/linux/module.h b/include/linux/module.h
fb10477
index 0c266b2..5a6374a 100644
fb10477
--- a/include/linux/module.h
fb10477
+++ b/include/linux/module.h
fb10477
@@ -184,6 +184,12 @@ const struct exception_table_entry *search_exception_tables(unsigned long add);
fb10477
 
fb10477
 struct notifier_block;
fb10477
 
fb10477
+#ifdef CONFIG_MODULE_SIG
fb10477
+extern void enforce_signed_modules(void);
fb10477
+#else
fb10477
+static inline void enforce_signed_modules(void) {};
fb10477
+#endif
fb10477
+
fb10477
 #ifdef CONFIG_MODULES
fb10477
 
fb10477
 extern int modules_disabled; /* for sysctl */
fb10477
diff --git a/kernel/module.c b/kernel/module.c
76b66ee
index 0e94acf..974139b 100644
fb10477
--- a/kernel/module.c
fb10477
+++ b/kernel/module.c
fb10477
@@ -3853,6 +3853,13 @@ void module_layout(struct module *mod,
fb10477
 EXPORT_SYMBOL(module_layout);
fb10477
 #endif
fb10477
 
fb10477
+#ifdef CONFIG_MODULE_SIG
fb10477
+void enforce_signed_modules(void)
fb10477
+{
fb10477
+	sig_enforce = true;
fb10477
+}
fb10477
+#endif
fb10477
+
fb10477
 bool secure_modules(void)
fb10477
 {
fb10477
 #ifdef CONFIG_MODULE_SIG
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From bb28516d346e6511f1e012321c48eb142763e539 Mon Sep 17 00:00:00 2001
fb10477
From: Josh Boyer <jwboyer@redhat.com>
fb10477
Date: Tue, 5 Feb 2013 19:25:05 -0500
76b66ee
Subject: [PATCH 12/14] efi: Disable secure boot if shim is in insecure mode
fb10477
fb10477
A user can manually tell the shim boot loader to disable validation of
fb10477
images it loads.  When a user does this, it creates a UEFI variable called
fb10477
MokSBState that does not have the runtime attribute set.  Given that the
fb10477
user explicitly disabled validation, we can honor that and not enable
fb10477
secure boot mode if that variable is set.
fb10477
fb10477
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
fb10477
---
fb10477
 arch/x86/boot/compressed/eboot.c | 20 +++++++++++++++++++-
fb10477
 1 file changed, 19 insertions(+), 1 deletion(-)
fb10477
fb10477
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
76b66ee
index 53bfe4f..946028b 100644
fb10477
--- a/arch/x86/boot/compressed/eboot.c
fb10477
+++ b/arch/x86/boot/compressed/eboot.c
76b66ee
@@ -864,8 +864,9 @@ fail:
fb10477
 
76b66ee
 static int get_secure_boot(void)
fb10477
 {
fb10477
-	u8 sb, setup;
fb10477
+	u8 sb, setup, moksbstate;
fb10477
 	unsigned long datasize = sizeof(sb);
fb10477
+	u32 attr;
fb10477
 	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
fb10477
 	efi_status_t status;
fb10477
 
76b66ee
@@ -889,6 +890,23 @@ static int get_secure_boot(void)
fb10477
 	if (setup == 1)
fb10477
 		return 0;
fb10477
 
fb10477
+	/* See if a user has put shim into insecure_mode.  If so, and the variable
fb10477
+	 * doesn't have the runtime attribute set, we might as well honor that.
fb10477
+	 */
fb10477
+	var_guid = EFI_SHIM_LOCK_GUID;
fb10477
+	status = efi_call_phys5(sys_table->runtime->get_variable,
fb10477
+				L"MokSBState", &var_guid, &attr, &datasize,
fb10477
+				&moksbstate);
fb10477
+
fb10477
+	/* If it fails, we don't care why.  Default to secure */
fb10477
+	if (status != EFI_SUCCESS)
fb10477
+		return 1;
fb10477
+
fb10477
+	if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS)) {
fb10477
+		if (moksbstate == 1)
fb10477
+			return 0;
fb10477
+	}
fb10477
+
fb10477
 	return 1;
fb10477
 }
fb10477
 
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From 4c8824bac8d4284e66c39c365ba84151f2d78e87 Mon Sep 17 00:00:00 2001
fb10477
From: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
Date: Tue, 27 Aug 2013 13:28:43 -0400
76b66ee
Subject: [PATCH 13/14] efi: Make EFI_SECURE_BOOT_SIG_ENFORCE depend on EFI
fb10477
fb10477
The functionality of the config option is dependent upon the platform being
fb10477
UEFI based.  Reflect this in the config deps.
fb10477
fb10477
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
---
fb10477
 arch/x86/Kconfig | 3 ++-
fb10477
 1 file changed, 2 insertions(+), 1 deletion(-)
fb10477
fb10477
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
fb10477
index 6a6c19b..10498ec 100644
fb10477
--- a/arch/x86/Kconfig
fb10477
+++ b/arch/x86/Kconfig
fb10477
@@ -1582,7 +1582,8 @@ config EFI_STUB
fb10477
 	  See Documentation/x86/efi-stub.txt for more information.
fb10477
 
fb10477
 config EFI_SECURE_BOOT_SIG_ENFORCE
fb10477
-        def_bool n
fb10477
+	def_bool n
fb10477
+	depends on EFI
fb10477
 	prompt "Force module signing when UEFI Secure Boot is enabled"
fb10477
 	---help---
fb10477
 	  UEFI Secure Boot provides a mechanism for ensuring that the
fb10477
-- 
fb10477
1.8.3.1
fb10477
fb10477
76b66ee
From 871b0ed1847c3c5413a4ca72ecf18735858f7708 Mon Sep 17 00:00:00 2001
fb10477
From: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
Date: Tue, 27 Aug 2013 13:33:03 -0400
76b66ee
Subject: [PATCH 14/14] efi: Add EFI_SECURE_BOOT bit
fb10477
fb10477
UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
fb10477
for use with efi_enabled.
fb10477
fb10477
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
fb10477
---
fb10477
 arch/x86/kernel/setup.c | 2 ++
fb10477
 include/linux/efi.h     | 1 +
fb10477
 2 files changed, 3 insertions(+)
fb10477
fb10477
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
fb10477
index deeb7bc..08dc16e 100644
fb10477
--- a/arch/x86/kernel/setup.c
fb10477
+++ b/arch/x86/kernel/setup.c
fb10477
@@ -1131,7 +1131,9 @@ void __init setup_arch(char **cmdline_p)
fb10477
 
fb10477
 #ifdef CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE
fb10477
 	if (boot_params.secure_boot) {
fb10477
+		set_bit(EFI_SECURE_BOOT, &x86_efi_facility);
fb10477
 		enforce_signed_modules();
fb10477
+		pr_info("Secure boot enabled\n");
fb10477
 	}
fb10477
 #endif
fb10477
 
fb10477
diff --git a/include/linux/efi.h b/include/linux/efi.h
fb10477
index 5f8f176..eed2202 100644
fb10477
--- a/include/linux/efi.h
fb10477
+++ b/include/linux/efi.h
fb10477
@@ -634,6 +634,7 @@ extern int __init efi_setup_pcdp_console(char *);
fb10477
 #define EFI_RUNTIME_SERVICES	3	/* Can we use runtime services? */
fb10477
 #define EFI_MEMMAP		4	/* Can we use EFI memory map? */
fb10477
 #define EFI_64BIT		5	/* Is the firmware 64-bit? */
fb10477
+#define EFI_SECURE_BOOT		6 /* Are we in Secure Boot mode? */
fb10477
 
fb10477
 #ifdef CONFIG_EFI
fb10477
 # ifdef CONFIG_X86
fb10477
-- 
fb10477
1.8.3.1
fb10477