Josh Boyer f0f4ff2
From 57c0dbcbafaa724313c672830ff0087f56a84c47 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:40:56 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 01/14] Secure boot: Add new capability
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Secure boot adds certain policy requirements, including that root must not
Josh Boyer 306dfcc
be able to do anything that could cause the kernel to execute arbitrary code.
Josh Boyer 306dfcc
The simplest way to handle this would seem to be to add a new capability
Josh Boyer 306dfcc
and gate various functionality on that. We'll then strip it from the initial
Josh Boyer 306dfcc
capability set if required.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfcc
---
be7ac52
 include/uapi/linux/capability.h | 6 +++++-
Josh Boyer 306dfcc
 1 file changed, 5 insertions(+), 1 deletion(-)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/include/linux/capability.h b/include/linux/capability.h
Josh Boyer f0f4ff2
index d10b7ed..4345bc8 100644
be7ac52
--- a/include/uapi/linux/capability.h
be7ac52
+++ b/include/uapi/linux/capability.h
Josh Boyer 306dfcc
@@ -364,7 +364,11 @@ struct cpu_vfs_cap_data {
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 #define CAP_BLOCK_SUSPEND    36
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
-#define CAP_LAST_CAP         CAP_BLOCK_SUSPEND
Josh Boyer f0f4ff2
+/* Allow things that trivially permit root to modify the running kernel */
Josh Boyer 306dfcc
+
Josh Boyer f0f4ff2
+#define CAP_COMPROMISE_KERNEL  37
Josh Boyer 306dfcc
+
Josh Boyer f0f4ff2
+#define CAP_LAST_CAP         CAP_COMPROMISE_KERNEL
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From 95fd8148be46036e20fc64c480104d2a2b454e27 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:40:57 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 02/14] PCI: Lock down BAR access in secure boot environments
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Any hardware that can potentially generate DMA has to be locked down from
Josh Boyer 306dfcc
userspace in order to avoid it being possible for an attacker to cause
Josh Boyer 306dfcc
arbitrary kernel behaviour. Default to paranoid - in future we can
Josh Boyer 306dfcc
potentially relax this for sufficiently IOMMU-isolated devices.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer 306dfcc
 drivers/pci/pci-sysfs.c | 9 +++++++++
Josh Boyer 306dfcc
 drivers/pci/proc.c      | 8 +++++++-
Josh Boyer 306dfcc
 drivers/pci/syscall.c   | 2 +-
Josh Boyer 306dfcc
 3 files changed, 17 insertions(+), 2 deletions(-)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
Josh Boyer f0f4ff2
index 6869009..c03fb85 100644
Josh Boyer 306dfcc
--- a/drivers/pci/pci-sysfs.c
Josh Boyer 306dfcc
+++ b/drivers/pci/pci-sysfs.c
Josh Boyer c115215
@@ -542,6 +542,9 @@ pci_write_config(struct file* filp, struct kobject *kobj,
Josh Boyer 306dfcc
 	loff_t init_off = off;
Josh Boyer 306dfcc
 	u8 *data = (u8*) buf;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	if (off > dev->cfg_size)
Josh Boyer 306dfcc
 		return 0;
Josh Boyer 306dfcc
 	if (off + count > dev->cfg_size) {
Josh Boyer c115215
@@ -844,6 +847,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
Josh Boyer 306dfcc
 	resource_size_t start, end;
Josh Boyer 306dfcc
 	int i;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	for (i = 0; i < PCI_ROM_RESOURCE; i++)
Josh Boyer 306dfcc
 		if (res == &pdev->resource[i])
Josh Boyer 306dfcc
 			break;
Josh Boyer c115215
@@ -951,6 +957,9 @@ pci_write_resource_io(struct file *filp, struct kobject *kobj,
Josh Boyer 306dfcc
 		      struct bin_attribute *attr, char *buf,
Josh Boyer 306dfcc
 		      loff_t off, size_t count)
Josh Boyer 306dfcc
 {
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
Josh Boyer 306dfcc
 }
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
Josh Boyer f0f4ff2
index 27911b5..ac8c9a5 100644
Josh Boyer 306dfcc
--- a/drivers/pci/proc.c
Josh Boyer 306dfcc
+++ b/drivers/pci/proc.c
Josh Boyer 306dfcc
@@ -135,6 +135,9 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
Josh Boyer 306dfcc
 	int size = dp->size;
Josh Boyer 306dfcc
 	int cnt;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	if (pos >= size)
Josh Boyer 306dfcc
 		return 0;
Josh Boyer 306dfcc
 	if (nbytes >= size)
Josh Boyer 306dfcc
@@ -211,6 +214,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
Josh Boyer 306dfcc
 #endif /* HAVE_PCI_MMAP */
Josh Boyer 306dfcc
 	int ret = 0;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	switch (cmd) {
Josh Boyer 306dfcc
 	case PCIIOC_CONTROLLER:
Josh Boyer 306dfcc
 		ret = pci_domain_nr(dev->bus);
Josh Boyer 306dfcc
@@ -251,7 +257,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
Josh Boyer 306dfcc
 	struct pci_filp_private *fpriv = file->private_data;
Josh Boyer 306dfcc
 	int i, ret;
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
-	if (!capable(CAP_SYS_RAWIO))
Josh Boyer f0f4ff2
+	if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
 		return -EPERM;
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 	/* Make sure the caller is mapping a real resource for this device */
Josh Boyer 306dfcc
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
Josh Boyer f0f4ff2
index e1c1ec5..97e785f 100644
Josh Boyer 306dfcc
--- a/drivers/pci/syscall.c
Josh Boyer 306dfcc
+++ b/drivers/pci/syscall.c
Josh Boyer 306dfcc
@@ -92,7 +92,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
Josh Boyer 306dfcc
 	u32 dword;
Josh Boyer 306dfcc
 	int err = 0;
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
-	if (!capable(CAP_SYS_ADMIN))
Josh Boyer f0f4ff2
+	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
 		return -EPERM;
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 	dev = pci_get_bus_and_slot(bus, dfn);
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From 2d23d2726583d79062e58abcc32c7dd027d312aa Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:40:58 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 03/14] x86: Lock down IO port access in secure boot
Josh Boyer 306dfcc
 environments
Josh Boyer 306dfcc
Josh Boyer 306dfcc
IO port access would permit users to gain access to PCI configuration
Josh Boyer 306dfcc
registers, which in turn (on a lot of hardware) give access to MMIO register
Josh Boyer 306dfcc
space. This would potentially permit root to trigger arbitrary DMA, so lock
Josh Boyer 306dfcc
it down by default.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer 306dfcc
 arch/x86/kernel/ioport.c | 4 ++--
Josh Boyer 306dfcc
 drivers/char/mem.c       | 3 +++
Josh Boyer 306dfcc
 2 files changed, 5 insertions(+), 2 deletions(-)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
Josh Boyer f0f4ff2
index 8c96897..a2578c4 100644
Josh Boyer 306dfcc
--- a/arch/x86/kernel/ioport.c
Josh Boyer 306dfcc
+++ b/arch/x86/kernel/ioport.c
Josh Boyer 306dfcc
@@ -28,7 +28,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
Josh Boyer 306dfcc
 		return -EINVAL;
Josh Boyer 306dfcc
-	if (turn_on && !capable(CAP_SYS_RAWIO))
Josh Boyer f0f4ff2
+	if (turn_on && (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL)))
Josh Boyer 306dfcc
 		return -EPERM;
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 	/*
Josh Boyer 306dfcc
@@ -102,7 +102,7 @@ long sys_iopl(unsigned int level, struct pt_regs *regs)
Josh Boyer 306dfcc
 		return -EINVAL;
Josh Boyer 306dfcc
 	/* Trying to gain more privileges? */
Josh Boyer 306dfcc
 	if (level > old) {
Josh Boyer 306dfcc
-		if (!capable(CAP_SYS_RAWIO))
Josh Boyer f0f4ff2
+		if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
 			return -EPERM;
Josh Boyer 306dfcc
 	}
Josh Boyer 306dfcc
 	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
Josh Boyer 306dfcc
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
Josh Boyer f0f4ff2
index e5eedfa..1e0a660 100644
Josh Boyer 306dfcc
--- a/drivers/char/mem.c
Josh Boyer 306dfcc
+++ b/drivers/char/mem.c
Josh Boyer 306dfcc
@@ -597,6 +597,9 @@ static ssize_t write_port(struct file *file, const char __user *buf,
Josh Boyer 306dfcc
 	unsigned long i = *ppos;
Josh Boyer 306dfcc
 	const char __user * tmp = buf;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	if (!access_ok(VERIFY_READ, buf, count))
Josh Boyer 306dfcc
 		return -EFAULT;
Josh Boyer 306dfcc
 	while (count-- > 0 && i < 65536) {
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From e063cb2f3a667d2540682d4bdbef91fdb23b1a84 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:40:59 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 04/14] ACPI: Limit access to custom_method
Josh Boyer 306dfcc
Josh Boyer 306dfcc
It must be impossible for even root to get code executed in kernel context
Josh Boyer 306dfcc
under a secure boot environment. custom_method effectively allows arbitrary
Josh Boyer 306dfcc
access to system memory, so it needs to have a capability check here.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer 306dfcc
 drivers/acpi/custom_method.c | 3 +++
Josh Boyer 306dfcc
 1 file changed, 3 insertions(+)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
Josh Boyer f0f4ff2
index 5d42c24..247d58b 100644
Josh Boyer 306dfcc
--- a/drivers/acpi/custom_method.c
Josh Boyer 306dfcc
+++ b/drivers/acpi/custom_method.c
Josh Boyer 306dfcc
@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
Josh Boyer 306dfcc
 	struct acpi_table_header table;
Josh Boyer 306dfcc
 	acpi_status status;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	if (!(*ppos)) {
Josh Boyer 306dfcc
 		/* parse the table header to get the table length */
Josh Boyer 306dfcc
 		if (count <= sizeof(struct acpi_table_header))
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From a1cccbd084c7355dcb2be7ae2934f168ce9ba9d5 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:41:00 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 05/14] asus-wmi: Restrict debugfs interface
Josh Boyer 306dfcc
Josh Boyer 306dfcc
We have no way of validating what all of the Asus WMI methods do on a
Josh Boyer 306dfcc
given machine, and there's a risk that some will allow hardware state to
Josh Boyer 306dfcc
be manipulated in such a way that arbitrary code can be executed in the
Josh Boyer 306dfcc
kernel. Add a capability check to prevent that.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer 306dfcc
 drivers/platform/x86/asus-wmi.c | 9 +++++++++
Josh Boyer 306dfcc
 1 file changed, 9 insertions(+)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
Josh Boyer f0f4ff2
index 2eb9fe8..61e055d 100644
Josh Boyer 306dfcc
--- a/drivers/platform/x86/asus-wmi.c
Josh Boyer 306dfcc
+++ b/drivers/platform/x86/asus-wmi.c
Josh Boyer f0f4ff2
@@ -1523,6 +1523,9 @@ static int show_dsts(struct seq_file *m, void *data)
Josh Boyer 306dfcc
 	int err;
Josh Boyer 306dfcc
 	u32 retval = -1;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 	if (err < 0)
Josh Boyer f0f4ff2
@@ -1539,6 +1542,9 @@ static int show_devs(struct seq_file *m, void *data)
Josh Boyer 306dfcc
 	int err;
Josh Boyer 306dfcc
 	u32 retval = -1;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
Josh Boyer 306dfcc
 				    &retval);
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
@@ -1563,6 +1569,9 @@ static int show_call(struct seq_file *m, void *data)
Josh Boyer 306dfcc
 	union acpi_object *obj;
Josh Boyer 306dfcc
 	acpi_status status;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
Josh Boyer 306dfcc
 				     1, asus->debug.method_id,
Josh Boyer 306dfcc
 				     &input, &output);
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From 1c9e53b626268f82509062751eda14e8572717cf Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:41:01 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 06/14] Restrict /dev/mem and /dev/kmem in secure boot setups
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Allowing users to write to address space makes it possible for the kernel
Josh Boyer 306dfcc
to be subverted. Restrict this when we need to protect the kernel.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer 306dfcc
 drivers/char/mem.c | 6 ++++++
Josh Boyer 306dfcc
 1 file changed, 6 insertions(+)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
Josh Boyer f0f4ff2
index 1e0a660..33eb947 100644
Josh Boyer 306dfcc
--- a/drivers/char/mem.c
Josh Boyer 306dfcc
+++ b/drivers/char/mem.c
Josh Boyer 306dfcc
@@ -158,6 +158,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
Josh Boyer 306dfcc
 	unsigned long copied;
Josh Boyer 306dfcc
 	void *ptr;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	if (!valid_phys_addr_range(p, count))
Josh Boyer 306dfcc
 		return -EFAULT;
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
@@ -530,6 +533,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
Josh Boyer 306dfcc
 	char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
Josh Boyer 306dfcc
 	int err = 0;
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
+		return -EPERM;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	if (p < (unsigned long) high_memory) {
Josh Boyer 306dfcc
 		unsigned long to_write = min_t(unsigned long, count,
Josh Boyer 306dfcc
 					       (unsigned long)high_memory - p);
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From fbf919bf372b9a7a08bdacac8129d47ced1b1f19 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:41:02 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 07/14] Secure boot: Add a dummy kernel parameter that will
Josh Boyer 306dfcc
 switch on Secure Boot mode
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
This forcibly drops CAP_COMPROMISE_KERNEL from both cap_permitted and cap_bset
Josh Boyer 306dfcc
in the init_cred struct, which everything else inherits from.  This works on
Josh Boyer 306dfcc
any machine and can be used to develop even if the box doesn't have UEFI.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer f0f4ff2
 Documentation/kernel-parameters.txt |  7 +++++++
Josh Boyer f0f4ff2
 kernel/cred.c                       | 17 +++++++++++++++++
Josh Boyer f0f4ff2
 2 files changed, 24 insertions(+)
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
Josh Boyer f0f4ff2
index 9b2b8d3..93978d5 100644
Josh Boyer f0f4ff2
--- a/Documentation/kernel-parameters.txt
Josh Boyer f0f4ff2
+++ b/Documentation/kernel-parameters.txt
Josh Boyer f0f4ff2
@@ -2562,6 +2562,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Josh Boyer f0f4ff2
 			Note: increases power consumption, thus should only be
Josh Boyer f0f4ff2
 			enabled if running jitter sensitive (HPC/RT) workloads.
Josh Boyer f0f4ff2
 
Josh Boyer f0f4ff2
+	secureboot_enable=
Josh Boyer f0f4ff2
+			[KNL] Enables an emulated UEFI Secure Boot mode.  This
Josh Boyer f0f4ff2
+			locks down various aspects of the kernel guarded by the
Josh Boyer f0f4ff2
+			CAP_COMPROMISE_KERNEL capability.  This includes things
Josh Boyer f0f4ff2
+			like /dev/mem, IO port access, and other areas.  It can
Josh Boyer f0f4ff2
+			be used on non-UEFI machines for testing purposes.
Josh Boyer f0f4ff2
+
Josh Boyer f0f4ff2
 	security=	[SECURITY] Choose a security module to enable at boot.
Josh Boyer f0f4ff2
 			If this boot parameter is not specified, only the first
Josh Boyer f0f4ff2
 			security module asking for security registration will be
Josh Boyer 306dfcc
diff --git a/kernel/cred.c b/kernel/cred.c
Josh Boyer f0f4ff2
index de728ac..7e6e83f 100644
Josh Boyer 306dfcc
--- a/kernel/cred.c
Josh Boyer 306dfcc
+++ b/kernel/cred.c
Josh Boyer f0f4ff2
@@ -623,6 +623,23 @@ void __init cred_init(void)
Josh Boyer 306dfcc
 				     0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
Josh Boyer 306dfcc
 }
Josh Boyer 306dfcc
 
Josh Boyer f0f4ff2
+void __init secureboot_enable()
Josh Boyer 306dfcc
+{
Josh Boyer f0f4ff2
+	pr_info("Secure boot enabled\n");
Josh Boyer f0f4ff2
+	cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL);
Josh Boyer f0f4ff2
+	cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL);
Josh Boyer f0f4ff2
+}
Josh Boyer 306dfcc
+
Josh Boyer f0f4ff2
+/* Dummy Secure Boot enable option to fake out UEFI SB=1 */
Josh Boyer f0f4ff2
+static int __init secureboot_enable_opt(char *str)
Josh Boyer f0f4ff2
+{
Josh Boyer 306dfcc
+	int sb_enable = !!simple_strtol(str, NULL, 0);
Josh Boyer f0f4ff2
+	if (sb_enable)
Josh Boyer f0f4ff2
+		secureboot_enable();
Josh Boyer 306dfcc
+	return 1;
Josh Boyer 306dfcc
+}
Josh Boyer f0f4ff2
+__setup("secureboot_enable=", secureboot_enable_opt);
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 /**
Josh Boyer 306dfcc
  * prepare_kernel_cred - Prepare a set of credentials for a kernel service
Josh Boyer 306dfcc
  * @daemon: A userspace daemon to be used as a reference
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From 43ed7865d867ae692e30227d66fa58cdecbd9269 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:41:03 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 08/14] efi: Enable secure boot lockdown automatically when
Josh Boyer 306dfcc
 enabled in firmware
Josh Boyer 306dfcc
Josh Boyer 306dfcc
The firmware has a set of flags that indicate whether secure boot is enabled
Josh Boyer 306dfcc
and enforcing. Use them to indicate whether the kernel should lock itself
Josh Boyer 306dfcc
down.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer f0f4ff2
 Documentation/x86/zero-page.txt  |  2 ++
Josh Boyer 306dfcc
 arch/x86/boot/compressed/eboot.c | 32 ++++++++++++++++++++++++++++++++
Josh Boyer 306dfcc
 arch/x86/include/asm/bootparam.h |  3 ++-
Josh Boyer 306dfcc
 arch/x86/kernel/setup.c          |  3 +++
Josh Boyer 306dfcc
 include/linux/cred.h             |  2 ++
Josh Boyer f0f4ff2
 5 files changed, 41 insertions(+), 1 deletion(-)
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
Josh Boyer f0f4ff2
index cf5437d..7f9ed48 100644
Josh Boyer f0f4ff2
--- a/Documentation/x86/zero-page.txt
Josh Boyer f0f4ff2
+++ b/Documentation/x86/zero-page.txt
Josh Boyer f0f4ff2
@@ -27,6 +27,8 @@ Offset	Proto	Name		Meaning
Josh Boyer f0f4ff2
 1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
Josh Boyer f0f4ff2
 1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
Josh Boyer f0f4ff2
 				(below)
Josh Boyer f0f4ff2
+1EB/001	ALL	kbd_status	Numlock is enabled
Josh Boyer f0f4ff2
+1EC/001	ALL	secure_boot	Kernel should enable secure boot lockdowns
Josh Boyer f0f4ff2
 290/040	ALL	edd_mbr_sig_buffer EDD MBR signatures
Josh Boyer f0f4ff2
 2D0/A00	ALL	e820_map	E820 memory map table
Josh Boyer f0f4ff2
 				(array of struct e820entry)
Josh Boyer 306dfcc
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
Josh Boyer 306dfcc
index b3e0227..3789356 100644
Josh Boyer 306dfcc
--- a/arch/x86/boot/compressed/eboot.c
Josh Boyer 306dfcc
+++ b/arch/x86/boot/compressed/eboot.c
Josh Boyer 306dfcc
@@ -724,6 +724,36 @@ fail:
Josh Boyer 306dfcc
 	return status;
Josh Boyer 306dfcc
 }
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
+static int get_secure_boot(efi_system_table_t *_table)
Josh Boyer 306dfcc
+{
Josh Boyer 306dfcc
+	u8 sb, setup;
Josh Boyer 306dfcc
+	unsigned long datasize = sizeof(sb);
Josh Boyer 306dfcc
+	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
Josh Boyer 306dfcc
+	efi_status_t status;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+	status = efi_call_phys5(sys_table->runtime->get_variable,
Josh Boyer 306dfcc
+				L"SecureBoot", &var_guid, NULL, &datasize, &sb);
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+	if (status != EFI_SUCCESS)
Josh Boyer 306dfcc
+		return 0;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+	if (sb == 0)
Josh Boyer 306dfcc
+		return 0;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+	status = efi_call_phys5(sys_table->runtime->get_variable,
Josh Boyer 306dfcc
+				L"SetupMode", &var_guid, NULL, &datasize,
Josh Boyer 306dfcc
+				&setup);
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+	if (status != EFI_SUCCESS)
Josh Boyer 306dfcc
+		return 0;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+	if (setup == 1)
Josh Boyer 306dfcc
+		return 0;
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
+	return 1;
Josh Boyer 306dfcc
+}
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 /*
Josh Boyer 306dfcc
  * Because the x86 boot code expects to be passed a boot_params we
Josh Boyer 306dfcc
  * need to create one ourselves (usually the bootloader would create
Josh Boyer 306dfcc
@@ -1018,6 +1048,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
Josh Boyer 306dfcc
 	if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
Josh Boyer 306dfcc
 		goto fail;
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
+	boot_params->secure_boot = get_secure_boot(sys_table);
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	setup_graphics(boot_params);
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 	status = efi_call_phys3(sys_table->boottime->allocate_pool,
Josh Boyer 306dfcc
diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h
Josh Boyer 306dfcc
index 2ad874c..c7338e0 100644
Josh Boyer 306dfcc
--- a/arch/x86/include/asm/bootparam.h
Josh Boyer 306dfcc
+++ b/arch/x86/include/asm/bootparam.h
Josh Boyer 306dfcc
@@ -114,7 +114,8 @@ struct boot_params {
Josh Boyer 306dfcc
 	__u8  eddbuf_entries;				/* 0x1e9 */
Josh Boyer 306dfcc
 	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
Josh Boyer 306dfcc
 	__u8  kbd_status;				/* 0x1eb */
Josh Boyer 306dfcc
-	__u8  _pad6[5];					/* 0x1ec */
Josh Boyer 306dfcc
+	__u8  secure_boot;				/* 0x1ec */
Josh Boyer 306dfcc
+	__u8  _pad6[4];					/* 0x1ed */
Josh Boyer 306dfcc
 	struct setup_header hdr;    /* setup header */	/* 0x1f1 */
Josh Boyer 306dfcc
 	__u8  _pad7[0x290-0x1f1-sizeof(struct setup_header)];
Josh Boyer 306dfcc
 	__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];	/* 0x290 */
Josh Boyer 306dfcc
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
Josh Boyer 306dfcc
index f4b9b80..239bf2a 100644
Josh Boyer 306dfcc
--- a/arch/x86/kernel/setup.c
Josh Boyer 306dfcc
+++ b/arch/x86/kernel/setup.c
Josh Boyer 306dfcc
@@ -947,6 +947,9 @@ void __init setup_arch(char **cmdline_p)
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
 	io_delay_init();
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
+	if (boot_params.secure_boot)
Josh Boyer 306dfcc
+		secureboot_enable();
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 	/*
Josh Boyer 306dfcc
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
Josh Boyer 306dfcc
 	 */
Josh Boyer 306dfcc
diff --git a/include/linux/cred.h b/include/linux/cred.h
Josh Boyer 306dfcc
index ebbed2c..a24faf1 100644
Josh Boyer 306dfcc
--- a/include/linux/cred.h
Josh Boyer 306dfcc
+++ b/include/linux/cred.h
Josh Boyer 306dfcc
@@ -170,6 +170,8 @@ extern int set_security_override_from_ctx(struct cred *, const char *);
Josh Boyer 306dfcc
 extern int set_create_files_as(struct cred *, struct inode *);
Josh Boyer 306dfcc
 extern void __init cred_init(void);
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
+extern void secureboot_enable(void);
Josh Boyer 306dfcc
+
Josh Boyer 306dfcc
 /*
Josh Boyer 306dfcc
  * check for validity of credentials
Josh Boyer 306dfcc
  */
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From 3acf1ceb5f6f3be9103c9da16ddc24afc6d8b02a Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:41:04 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 09/14] acpi: Ignore acpi_rsdp kernel parameter in a secure
Josh Boyer 306dfcc
 boot environment
Josh Boyer 306dfcc
Josh Boyer 306dfcc
This option allows userspace to pass the RSDP address to the kernel.  This
Josh Boyer 306dfcc
could potentially be used to circumvent the secure boot trust model.
Josh Boyer f0f4ff2
We ignore the setting if we don't have the CAP_COMPROMISE_KERNEL capability.
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer 306dfcc
 drivers/acpi/osl.c | 2 +-
Josh Boyer 306dfcc
 1 file changed, 1 insertion(+), 1 deletion(-)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
Josh Boyer f0f4ff2
index 9eaf708..f94341b 100644
Josh Boyer 306dfcc
--- a/drivers/acpi/osl.c
Josh Boyer 306dfcc
+++ b/drivers/acpi/osl.c
Josh Boyer 306dfcc
@@ -246,7 +246,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp);
Josh Boyer 306dfcc
 acpi_physical_address __init acpi_os_get_root_pointer(void)
Josh Boyer 306dfcc
 {
Josh Boyer 306dfcc
 #ifdef CONFIG_KEXEC
Josh Boyer 306dfcc
-	if (acpi_rsdp)
Josh Boyer f0f4ff2
+	if (acpi_rsdp && capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 306dfcc
 		return acpi_rsdp;
Josh Boyer 306dfcc
 #endif
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
From 03fb06d272ddc1062e610521c5cfdbe42f251209 Mon Sep 17 00:00:00 2001
Josh Boyer f0f4ff2
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer f0f4ff2
Date: Thu, 20 Sep 2012 10:41:05 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 10/14] SELinux: define mapping for new Secure Boot capability
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
Add the name of the new Secure Boot capability.  This allows SELinux
Josh Boyer f0f4ff2
policies to properly map CAP_COMPROMISE_KERNEL to the appropriate
Josh Boyer f0f4ff2
capability class.
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer f0f4ff2
---
Josh Boyer f0f4ff2
 security/selinux/include/classmap.h | 4 ++--
Josh Boyer f0f4ff2
 1 file changed, 2 insertions(+), 2 deletions(-)
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
Josh Boyer f0f4ff2
index df2de54..70e2834 100644
Josh Boyer f0f4ff2
--- a/security/selinux/include/classmap.h
Josh Boyer f0f4ff2
+++ b/security/selinux/include/classmap.h
Josh Boyer f0f4ff2
@@ -146,8 +146,8 @@ struct security_class_mapping secclass_map[] = {
Josh Boyer f0f4ff2
 	{ "memprotect", { "mmap_zero", NULL } },
Josh Boyer f0f4ff2
 	{ "peer", { "recv", NULL } },
Josh Boyer f0f4ff2
 	{ "capability2",
Josh Boyer f0f4ff2
-	  { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend",
Josh Boyer f0f4ff2
-	    NULL } },
Josh Boyer f0f4ff2
+	  { "mac_override", "mac_admin", "syslog", "wake_alarm",
Josh Boyer f0f4ff2
+	    "block_suspend", "compromise_kernel", NULL } },
Josh Boyer f0f4ff2
 	{ "kernel_service", { "use_as_override", "create_files_as", NULL } },
Josh Boyer f0f4ff2
 	{ "tun_socket",
Josh Boyer f0f4ff2
 	  { COMMON_SOCK_PERMS, NULL } },
Josh Boyer f0f4ff2
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
From 0cfaa5ecf01f8eaaa2a84d88b7258a94ac9a1bfe Mon Sep 17 00:00:00 2001
Josh Boyer f0f4ff2
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
Date: Tue, 4 Sep 2012 11:55:13 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 11/14] kexec: Disable in a secure boot environment
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
kexec could be used as a vector for a malicious user to use a signed kernel
Josh Boyer f0f4ff2
to circumvent the secure boot trust model. In the long run we'll want to
Josh Boyer f0f4ff2
support signed kexec payloads, but for the moment we should just disable
Josh Boyer f0f4ff2
loading entirely in that situation.
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff2
---
Josh Boyer f0f4ff2
 kernel/kexec.c | 2 +-
Josh Boyer f0f4ff2
 1 file changed, 1 insertion(+), 1 deletion(-)
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
diff --git a/kernel/kexec.c b/kernel/kexec.c
Josh Boyer f0f4ff2
index 0668d58..8b976a5 100644
Josh Boyer f0f4ff2
--- a/kernel/kexec.c
Josh Boyer f0f4ff2
+++ b/kernel/kexec.c
Josh Boyer f0f4ff2
@@ -944,7 +944,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
Josh Boyer f0f4ff2
 	int result;
Josh Boyer f0f4ff2
 
Josh Boyer f0f4ff2
 	/* We only trust the superuser with rebooting the system. */
Josh Boyer f0f4ff2
-	if (!capable(CAP_SYS_BOOT))
Josh Boyer f0f4ff2
+	if (!capable(CAP_SYS_BOOT) || !capable(CAP_COMPROMISE_KERNEL))
Josh Boyer f0f4ff2
 		return -EPERM;
Josh Boyer f0f4ff2
 
Josh Boyer f0f4ff2
 	/*
Josh Boyer f0f4ff2
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer f0f4ff2
From 895c46276788b3711aee05a1a1d685eff69d48b9 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfcc
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 306dfcc
Date: Mon, 25 Jun 2012 21:29:46 -0400
Josh Boyer f0f4ff2
Subject: [PATCH 12/14] Documentation: kernel-parameters.txt remove
Josh Boyer 306dfcc
 capability.disable
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Remove the documentation for capability.disable.  The code supporting this
Josh Boyer 306dfcc
parameter was removed with:
Josh Boyer 306dfcc
Josh Boyer 306dfcc
	commit 5915eb53861c5776cfec33ca4fcc1fd20d66dd27
Josh Boyer 306dfcc
	Author: Miklos Szeredi <mszeredi@suse.cz>
Josh Boyer 306dfcc
	Date:   Thu Jul 3 20:56:05 2008 +0200
Josh Boyer 306dfcc
Josh Boyer 306dfcc
    	security: remove dummy module
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 306dfcc
---
Josh Boyer 306dfcc
 Documentation/kernel-parameters.txt | 6 ------
Josh Boyer 306dfcc
 1 file changed, 6 deletions(-)
Josh Boyer 306dfcc
Josh Boyer 306dfcc
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
Josh Boyer f0f4ff2
index 93978d5..e3e5f8c 100644
Josh Boyer 306dfcc
--- a/Documentation/kernel-parameters.txt
Josh Boyer 306dfcc
+++ b/Documentation/kernel-parameters.txt
Josh Boyer 306dfcc
@@ -446,12 +446,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
Josh Boyer 306dfcc
 			possible to determine what the correct size should be.
Josh Boyer 306dfcc
 			This option provides an override for these situations.
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
-	capability.disable=
Josh Boyer 306dfcc
-			[SECURITY] Disable capabilities.  This would normally
Josh Boyer 306dfcc
-			be used only if an alternative security model is to be
Josh Boyer 306dfcc
-			configured.  Potentially dangerous and should only be
Josh Boyer 306dfcc
-			used if you are entirely sure of the consequences.
Josh Boyer 306dfcc
-
Josh Boyer 306dfcc
 	ccw_timeout_log [S390]
Josh Boyer 306dfcc
 			See Documentation/s390/CommonIO for details.
Josh Boyer 306dfcc
 
Josh Boyer 306dfcc
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 306dfcc
Josh Boyer 306dfcc
Josh Boyer 1b028bf
From 1cc529e97756554953187fe48b9b8cf0e24b9bc7 Mon Sep 17 00:00:00 2001
Josh Boyer f0f4ff2
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 1b028bf
Date: Fri, 5 Oct 2012 10:12:48 -0400
Josh Boyer 1b028bf
Subject: [PATCH] modsign: Always enforce module signing in a Secure Boot
Josh Boyer f0f4ff2
 environment
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
If a machine is booted into a Secure Boot environment, we need to
Josh Boyer f0f4ff2
protect the trust model.  This requires that all modules be signed
Josh Boyer 1b028bf
with a key that is in the kernel's _modsign keyring.  The checks for
Josh Boyer 1b028bf
this are already done via the 'sig_enforce' module parameter.  Make
Josh Boyer 1b028bf
this visible within the kernel and force it to be true.
Josh Boyer f0f4ff2
Josh Boyer f0f4ff2
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer f0f4ff2
---
Josh Boyer 1b028bf
 kernel/cred.c   | 8 ++++++++
Josh Boyer f0f4ff2
 kernel/module.c | 4 ++--
Josh Boyer 1b028bf
 2 files changed, 10 insertions(+), 2 deletions(-)
Josh Boyer f0f4ff2
Josh Boyer 1b028bf
diff --git a/kernel/cred.c b/kernel/cred.c
Josh Boyer 1b028bf
index 7e6e83f..2b0b980 100644
Josh Boyer 1b028bf
--- a/kernel/cred.c
Josh Boyer 1b028bf
+++ b/kernel/cred.c
Josh Boyer 1b028bf
@@ -623,11 +623,19 @@ void __init cred_init(void)
Josh Boyer 1b028bf
 				     0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
Josh Boyer 1b028bf
 }
Josh Boyer 1b028bf
 
Josh Boyer 393a84a
+#ifdef CONFIG_MODULE_SIG
Josh Boyer 1b028bf
+extern bool sig_enforce;
Josh Boyer 1b028bf
+#endif
Josh Boyer 1b028bf
+
Josh Boyer 1b028bf
 void __init secureboot_enable()
Josh Boyer 1b028bf
 {
Josh Boyer 1b028bf
 	pr_info("Secure boot enabled\n");
Josh Boyer 1b028bf
 	cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL);
Josh Boyer 1b028bf
 	cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL);
Josh Boyer 393a84a
+#ifdef CONFIG_MODULE_SIG
Josh Boyer 1b028bf
+	/* Enable module signature enforcing */
Josh Boyer 1b028bf
+	sig_enforce = true;
Josh Boyer 1b028bf
+#endif
Josh Boyer 1b028bf
 }
Josh Boyer 1b028bf
 
Josh Boyer 1b028bf
 /* Dummy Secure Boot enable option to fake out UEFI SB=1 */
Josh Boyer f0f4ff2
diff --git a/kernel/module.c b/kernel/module.c
Josh Boyer 1b028bf
index de16959..7d4c50a 100644
Josh Boyer f0f4ff2
--- a/kernel/module.c
Josh Boyer f0f4ff2
+++ b/kernel/module.c
Josh Boyer 1b028bf
@@ -106,9 +106,9 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
Josh Boyer 1b028bf
 
Josh Boyer 1b028bf
 #ifdef CONFIG_MODULE_SIG
Josh Boyer 1b028bf
 #ifdef CONFIG_MODULE_SIG_FORCE
Josh Boyer 1b028bf
-static bool sig_enforce = true;
Josh Boyer 1b028bf
+bool sig_enforce = true;
Josh Boyer 1b028bf
 #else
Josh Boyer 1b028bf
-static bool sig_enforce = false;
Josh Boyer 1b028bf
+bool sig_enforce = false;
Josh Boyer 1b028bf
 
Josh Boyer 1b028bf
 static int param_set_bool_enable_only(const char *val,
Josh Boyer 1b028bf
 				      const struct kernel_param *kp)
Josh Boyer f0f4ff2
-- 
Josh Boyer f0f4ff2
1.7.11.4
Josh Boyer 1932bb1
Josh Boyer 5e72ee3
From 945f3829d0d376c5e0c790b57c4fa9e875d602d3 Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee3
From: Dave Howells <dhowells@redhat.com>
Josh Boyer 5e72ee3
Date: Tue, 23 Oct 2012 09:30:54 -0400
Josh Boyer 5e72ee3
Subject: [PATCH 1/2] Add EFI signature data types, such as are used for
Josh Boyer 5e72ee3
 containing hashes, keys and certificates for
Josh Boyer 5e72ee3
 cryptographic verification.
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Signed-off-by: David Howells <dhowells@redhat.com>
Josh Boyer 5e72ee3
---
Josh Boyer 5e72ee3
 include/linux/efi.h | 20 ++++++++++++++++++++
Josh Boyer 5e72ee3
 1 file changed, 20 insertions(+)
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer 5e72ee3
index 8670eb1..836c797 100644
Josh Boyer 5e72ee3
--- a/include/linux/efi.h
Josh Boyer 5e72ee3
+++ b/include/linux/efi.h
Josh Boyer 5e72ee3
@@ -312,6 +312,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
Josh Boyer 5e72ee3
 #define EFI_FILE_SYSTEM_GUID \
Josh Boyer 5e72ee3
     EFI_GUID(  0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+#define EFI_CERT_SHA256_GUID \
Josh Boyer 5e72ee3
+    EFI_GUID(  0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 )
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+#define EFI_CERT_X509_GUID \
Josh Boyer 5e72ee3
+    EFI_GUID(  0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 )
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 typedef struct {
Josh Boyer 5e72ee3
 	efi_guid_t guid;
Josh Boyer 5e72ee3
 	u64 table;
Josh Boyer 5e72ee3
@@ -447,6 +453,20 @@ typedef struct {
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 #define EFI_INVALID_TABLE_ADDR		(~0UL)
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+typedef struct  {
Josh Boyer 5e72ee3
+	efi_guid_t signature_owner;
Josh Boyer 5e72ee3
+	u8 signature_data[];
Josh Boyer 5e72ee3
+} efi_signature_data_t;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+typedef struct {
Josh Boyer 5e72ee3
+	efi_guid_t signature_type;
Josh Boyer 5e72ee3
+	u32 signature_list_size;
Josh Boyer 5e72ee3
+	u32 signature_header_size;
Josh Boyer 5e72ee3
+	u32 signature_size;
Josh Boyer 5e72ee3
+	u8 signature_header[];
Josh Boyer 5e72ee3
+	/* efi_signature_data_t signatures[][] */
Josh Boyer 5e72ee3
+} efi_signature_list_t;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 /*
Josh Boyer 5e72ee3
  * All runtime access to EFI goes through this structure:
Josh Boyer 5e72ee3
  */
Josh Boyer 5e72ee3
-- 
Josh Boyer 5e72ee3
1.7.12.1
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
From 5934634101936bc4ee4636df7269e00c4979911c Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee3
From: Dave Howells <dhowells@redhat.com>
Josh Boyer 5e72ee3
Date: Tue, 23 Oct 2012 09:36:28 -0400
Josh Boyer 5e72ee3
Subject: [PATCH 2/2] Add an EFI signature blob parser and key loader.  X.509
Josh Boyer 5e72ee3
 certificates are loaded into the specified keyring as
Josh Boyer 5e72ee3
 asymmetric type keys.
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Signed-off-by: David Howells <dhowells@redhat.com>
Josh Boyer 5e72ee3
---
Josh Boyer 5e72ee3
 crypto/asymmetric_keys/Kconfig      |   7 +++
Josh Boyer 5e72ee3
 crypto/asymmetric_keys/Makefile     |   1 +
Josh Boyer 5e72ee3
 crypto/asymmetric_keys/efi_parser.c | 107 ++++++++++++++++++++++++++++++++++++
Josh Boyer 5e72ee3
 include/linux/efi.h                 |   4 ++
Josh Boyer 5e72ee3
 4 files changed, 119 insertions(+)
Josh Boyer 5e72ee3
 create mode 100644 crypto/asymmetric_keys/efi_parser.c
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
Josh Boyer 5e72ee3
index 6d2c2ea..eb53fc3 100644
Josh Boyer 5e72ee3
--- a/crypto/asymmetric_keys/Kconfig
Josh Boyer 5e72ee3
+++ b/crypto/asymmetric_keys/Kconfig
Josh Boyer 5e72ee3
@@ -35,4 +35,11 @@ config X509_CERTIFICATE_PARSER
Josh Boyer 5e72ee3
 	  data and provides the ability to instantiate a crypto key from a
Josh Boyer 5e72ee3
 	  public key packet found inside the certificate.
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+config EFI_SIGNATURE_LIST_PARSER
Josh Boyer 5e72ee3
+	bool "EFI signature list parser"
Josh Boyer 5e72ee3
+	select X509_CERTIFICATE_PARSER
Josh Boyer 5e72ee3
+	help
Josh Boyer 5e72ee3
+	  This option provides support for parsing EFI signature lists for
Josh Boyer 5e72ee3
+	  X.509 certificates and turning them into keys.
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 endif # ASYMMETRIC_KEY_TYPE
Josh Boyer 5e72ee3
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
Josh Boyer 5e72ee3
index 0727204..cd8388e 100644
Josh Boyer 5e72ee3
--- a/crypto/asymmetric_keys/Makefile
Josh Boyer 5e72ee3
+++ b/crypto/asymmetric_keys/Makefile
Josh Boyer 5e72ee3
@@ -8,6 +8,7 @@ asymmetric_keys-y := asymmetric_type.o signature.o
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
Josh Boyer 5e72ee3
 obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
Josh Boyer 5e72ee3
+obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 #
Josh Boyer 5e72ee3
 # X.509 Certificate handling
Josh Boyer 5e72ee3
diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c
Josh Boyer 5e72ee3
new file mode 100644
Josh Boyer 5e72ee3
index 0000000..59b859a
Josh Boyer 5e72ee3
--- /dev/null
Josh Boyer 5e72ee3
+++ b/crypto/asymmetric_keys/efi_parser.c
Josh Boyer 5e72ee3
@@ -0,0 +1,107 @@
Josh Boyer 5e72ee3
+/* EFI signature/key/certificate list parser
Josh Boyer 5e72ee3
+ *
Josh Boyer 5e72ee3
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
Josh Boyer 5e72ee3
+ * Written by David Howells (dhowells@redhat.com)
Josh Boyer 5e72ee3
+ *
Josh Boyer 5e72ee3
+ * This program is free software; you can redistribute it and/or
Josh Boyer 5e72ee3
+ * modify it under the terms of the GNU General Public Licence
Josh Boyer 5e72ee3
+ * as published by the Free Software Foundation; either version
Josh Boyer 5e72ee3
+ * 2 of the Licence, or (at your option) any later version.
Josh Boyer 5e72ee3
+ */
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+#define pr_fmt(fmt) "EFI: "fmt
Josh Boyer 5e72ee3
+#include <linux/module.h>
Josh Boyer 5e72ee3
+#include <linux/printk.h>
Josh Boyer 5e72ee3
+#include <linux/err.h>
Josh Boyer 5e72ee3
+#include <linux/efi.h>
Josh Boyer 5e72ee3
+#include <keys/asymmetric-type.h>
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+/**
Josh Boyer 5e72ee3
+ * parse_efi_signature_list - Parse an EFI signature list for certificates
Josh Boyer 5e72ee3
+ * @data: The data blob to parse
Josh Boyer 5e72ee3
+ * @size: The size of the data blob
Josh Boyer 5e72ee3
+ * @keyring: The keyring to add extracted keys to
Josh Boyer 5e72ee3
+ */
Josh Boyer 5e72ee3
+int __init parse_efi_signature_list(const void *data, size_t size, struct key *keyring)
Josh Boyer 5e72ee3
+{
Josh Boyer 5e72ee3
+	unsigned offs = 0;
Josh Boyer 5e72ee3
+	size_t lsize, esize, hsize, elsize;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	pr_devel("-->%s(,%zu)\n", __func__, size);
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	while (size > 0) {
Josh Boyer 5e72ee3
+		efi_signature_list_t list;
Josh Boyer 5e72ee3
+		const efi_signature_data_t *elem;
Josh Boyer 5e72ee3
+		key_ref_t key;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+		if (size < sizeof(list))
Josh Boyer 5e72ee3
+			return -EBADMSG;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+		memcpy(&list, data, sizeof(list));
Josh Boyer 5e72ee3
+		pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n",
Josh Boyer 5e72ee3
+			 offs,
Josh Boyer 5e72ee3
+			 list.signature_type.b, list.signature_list_size,
Josh Boyer 5e72ee3
+			 list.signature_header_size, list.signature_size);
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+		lsize = list.signature_list_size;
Josh Boyer 5e72ee3
+		hsize = list.signature_header_size;
Josh Boyer 5e72ee3
+		esize = list.signature_size;
Josh Boyer 5e72ee3
+		elsize = lsize - sizeof(list) - hsize;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+		if (lsize > size) {
Josh Boyer 5e72ee3
+			pr_devel("<--%s() = -EBADMSG [overrun @%x]\n",
Josh Boyer 5e72ee3
+				 __func__, offs);
Josh Boyer 5e72ee3
+			return -EBADMSG;
Josh Boyer 5e72ee3
+		}
Josh Boyer 5e72ee3
+		if (lsize < sizeof(list) ||
Josh Boyer 5e72ee3
+		    lsize - sizeof(list) < hsize ||
Josh Boyer 5e72ee3
+		    esize < sizeof(*elem) ||
Josh Boyer 5e72ee3
+		    elsize < esize ||
Josh Boyer 5e72ee3
+		    elsize % esize != 0) {
Josh Boyer 5e72ee3
+			pr_devel("- bad size combo @%x\n", offs);
Josh Boyer 5e72ee3
+			continue;
Josh Boyer 5e72ee3
+		}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+		if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) {
Josh Boyer 5e72ee3
+			data += lsize;
Josh Boyer 5e72ee3
+			size -= lsize;
Josh Boyer 5e72ee3
+			offs += lsize;
Josh Boyer 5e72ee3
+			continue;
Josh Boyer 5e72ee3
+		}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+		data += sizeof(list) + hsize;
Josh Boyer 5e72ee3
+		size -= sizeof(list) + hsize;
Josh Boyer 5e72ee3
+		offs += sizeof(list) + hsize;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+		for (; elsize > 0; elsize -= esize) {
Josh Boyer 5e72ee3
+			elem = data;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+			pr_devel("ELEM[%04x]\n", offs);
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+			key = key_create_or_update(
Josh Boyer 5e72ee3
+				make_key_ref(keyring, 1),
Josh Boyer 5e72ee3
+				"asymmetric",
Josh Boyer 5e72ee3
+				NULL,
Josh Boyer 5e72ee3
+				&elem->signature_data,
Josh Boyer 5e72ee3
+				esize - sizeof(*elem),
Josh Boyer 5e72ee3
+				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
Josh Boyer 5e72ee3
+				KEY_USR_VIEW,
Josh Boyer 5e72ee3
+				KEY_ALLOC_NOT_IN_QUOTA);
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+			if (IS_ERR(key))
Josh Boyer 5e72ee3
+				pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
Josh Boyer 5e72ee3
+				       PTR_ERR(key));
Josh Boyer 5e72ee3
+			else
Josh Boyer 5e72ee3
+				pr_notice("Loaded cert '%s'\n",
Josh Boyer 5e72ee3
+					  key_ref_to_ptr(key)->description);
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+			data += esize;
Josh Boyer 5e72ee3
+			size -= esize;
Josh Boyer 5e72ee3
+			offs += esize;
Josh Boyer 5e72ee3
+		}
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	return 0;
Josh Boyer 5e72ee3
+}
Josh Boyer 5e72ee3
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer 5e72ee3
index 836c797..9cc3250 100644
Josh Boyer 5e72ee3
--- a/include/linux/efi.h
Josh Boyer 5e72ee3
+++ b/include/linux/efi.h
Josh Boyer 5e72ee3
@@ -536,6 +536,10 @@ extern int efi_set_rtc_mmss(unsigned long nowtime);
Josh Boyer 5e72ee3
 extern void efi_reserve_boot_services(void);
Josh Boyer 5e72ee3
 extern struct efi_memory_map memmap;
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+struct key;
Josh Boyer 5e72ee3
+extern int __init parse_efi_signature_list(const void *data, size_t size,
Josh Boyer 5e72ee3
+					   struct key *keyring);
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 /**
Josh Boyer 5e72ee3
  * efi_range_is_wc - check the WC bit on an address range
Josh Boyer 5e72ee3
  * @start: starting kvirt address
Josh Boyer 5e72ee3
-- 
Josh Boyer 5e72ee3
1.7.12.1
Josh Boyer 5e72ee3
Josh Boyer a9993c7
From a06f449cee6152ce8f0a051593fceb82d26e4f16 Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee3
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
Date: Fri, 26 Oct 2012 12:29:49 -0400
Josh Boyer a9993c7
Subject: [PATCH] EFI: Add in-kernel variable to determine if Secure Boot is
Josh Boyer a9993c7
 enabled
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
There are a few cases where in-kernel functions may need to know if
Josh Boyer 5e72ee3
Secure Boot is enabled.  The added capability check cannot be used as the
Josh Boyer 5e72ee3
kernel can't drop it's own capabilites, so we add a global variable
Josh Boyer 5e72ee3
similar to efi_enabled so they can determine if Secure Boot is enabled.
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
---
Josh Boyer a9993c7
 arch/x86/kernel/setup.c     | 6 +++++-
Josh Boyer 5e72ee3
 arch/x86/platform/efi/efi.c | 2 ++
Josh Boyer 5e72ee3
 include/linux/efi.h         | 3 +++
Josh Boyer a9993c7
 3 files changed, 10 insertions(+), 1 deletion(-)
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
Josh Boyer a9993c7
index b4f4666..db74940 100644
Josh Boyer 5e72ee3
--- a/arch/x86/kernel/setup.c
Josh Boyer 5e72ee3
+++ b/arch/x86/kernel/setup.c
Josh Boyer a9993c7
@@ -961,8 +961,12 @@ void __init setup_arch(char **cmdline_p)
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 	io_delay_init();
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
-	if (boot_params.secure_boot)
Josh Boyer 5e72ee3
+	if (boot_params.secure_boot) {
Josh Boyer 5e72ee3
 		secureboot_enable();
Josh Boyer a9993c7
+#ifdef CONFIG_EFI
Josh Boyer 5e72ee3
+		secure_boot_enabled = 1;
Josh Boyer a9993c7
+#endif
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 	/*
Josh Boyer 5e72ee3
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
Josh Boyer 5e72ee3
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
Josh Boyer a9993c7
index 72d8899..882d794 100644
Josh Boyer 5e72ee3
--- a/arch/x86/platform/efi/efi.c
Josh Boyer 5e72ee3
+++ b/arch/x86/platform/efi/efi.c
Josh Boyer a9993c7
@@ -53,6 +53,8 @@
Josh Boyer 5e72ee3
 int efi_enabled;
Josh Boyer 5e72ee3
 EXPORT_SYMBOL(efi_enabled);
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+int secure_boot_enabled;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 struct efi __read_mostly efi = {
Josh Boyer 5e72ee3
 	.mps        = EFI_INVALID_TABLE_ADDR,
Josh Boyer 5e72ee3
 	.acpi       = EFI_INVALID_TABLE_ADDR,
Josh Boyer 5e72ee3
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer a9993c7
index 54b5936..411997f 100644
Josh Boyer 5e72ee3
--- a/include/linux/efi.h
Josh Boyer 5e72ee3
+++ b/include/linux/efi.h
Josh Boyer a9993c7
@@ -575,11 +575,14 @@ extern int __init efi_setup_pcdp_console(char *);
Josh Boyer 5e72ee3
 # ifdef CONFIG_X86
Josh Boyer 5e72ee3
    extern int efi_enabled;
Josh Boyer 5e72ee3
    extern bool efi_64bit;
Josh Boyer 5e72ee3
+   extern int secure_boot_enabled;
Josh Boyer 5e72ee3
 # else
Josh Boyer 5e72ee3
 #  define efi_enabled 1
Josh Boyer 5e72ee3
+#  define secure_boot_enabled 0
Josh Boyer 5e72ee3
 # endif
Josh Boyer 5e72ee3
 #else
Josh Boyer 5e72ee3
 # define efi_enabled 0
Josh Boyer 5e72ee3
+# define secure_boot_enabled 0
Josh Boyer 5e72ee3
 #endif
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 /*
Josh Boyer 5e72ee3
-- 
Josh Boyer 5e72ee3
1.7.12.1
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
From 2a5f33b264daffd717b509bc5ac3cdc060b5573e Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee3
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
Date: Fri, 26 Oct 2012 12:36:24 -0400
Josh Boyer 5e72ee3
Subject: [PATCH 2/3] MODSIGN: Add module certificate blacklist keyring
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
This adds an additional keyring that is used to store certificates that
Josh Boyer 5e72ee3
are blacklisted.  This keyring is searched first when loading signed modules
Josh Boyer 5e72ee3
and if the module's certificate is found, it will refuse to load.  This is
Josh Boyer 5e72ee3
useful in cases where third party certificates are used for module signing.
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
---
Josh Boyer 5e72ee3
 init/Kconfig             |  8 ++++++++
Josh Boyer 5e72ee3
 kernel/modsign_pubkey.c  | 17 +++++++++++++++++
Josh Boyer 5e72ee3
 kernel/module-internal.h |  3 +++
Josh Boyer 5e72ee3
 kernel/module_signing.c  | 14 +++++++++++++-
Josh Boyer 5e72ee3
 4 files changed, 41 insertions(+), 1 deletion(-)
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
diff --git a/init/Kconfig b/init/Kconfig
Josh Boyer 5e72ee3
index 6fdd6e3..7a9bf00 100644
Josh Boyer 5e72ee3
--- a/init/Kconfig
Josh Boyer 5e72ee3
+++ b/init/Kconfig
Josh Boyer 5e72ee3
@@ -1602,6 +1602,14 @@ config MODULE_SIG_FORCE
Josh Boyer 5e72ee3
 	  Reject unsigned modules or signed modules for which we don't have a
Josh Boyer 5e72ee3
 	  key.  Without this, such modules will simply taint the kernel.
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+config MODULE_SIG_BLACKLIST
Josh Boyer 5e72ee3
+	bool "Support for blacklisting module signature certificates"
Josh Boyer 5e72ee3
+	depends on MODULE_SIG
Josh Boyer 5e72ee3
+	help
Josh Boyer 5e72ee3
+	  This adds support for keeping a blacklist of certificates that
Josh Boyer 5e72ee3
+	  should not pass module signature verification.  If a module is
Josh Boyer 5e72ee3
+	  signed with something in this keyring, the load will be rejected.
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 choice
Josh Boyer 5e72ee3
 	prompt "Which hash algorithm should modules be signed with?"
Josh Boyer 5e72ee3
 	depends on MODULE_SIG
Josh Boyer 5e72ee3
diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
Josh Boyer 5e72ee3
index 4646eb2..6d70783 100644
Josh Boyer 5e72ee3
--- a/kernel/modsign_pubkey.c
Josh Boyer 5e72ee3
+++ b/kernel/modsign_pubkey.c
Josh Boyer 5e72ee3
@@ -17,6 +17,9 @@
Josh Boyer 5e72ee3
 #include "module-internal.h"
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 struct key *modsign_keyring;
Josh Boyer 5e72ee3
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
Josh Boyer 5e72ee3
+struct key *modsign_blacklist;
Josh Boyer 5e72ee3
+#endif
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 extern __initdata const u8 modsign_certificate_list[];
Josh Boyer 5e72ee3
 extern __initdata const u8 modsign_certificate_list_end[];
Josh Boyer 5e72ee3
@@ -52,6 +55,20 @@ static __init int module_verify_init(void)
Josh Boyer 5e72ee3
 	if (key_instantiate_and_link(modsign_keyring, NULL, 0, NULL, NULL) < 0)
Josh Boyer 5e72ee3
 		panic("Can't instantiate module signing keyring\n");
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
Josh Boyer 5e72ee3
+	modsign_blacklist = key_alloc(&key_type_keyring, ".modsign_blacklist",
Josh Boyer 5e72ee3
+				    KUIDT_INIT(0), KGIDT_INIT(0),
Josh Boyer 5e72ee3
+				    current_cred(),
Josh Boyer 5e72ee3
+				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
Josh Boyer 5e72ee3
+				    KEY_USR_VIEW | KEY_USR_READ,
Josh Boyer 5e72ee3
+				    KEY_ALLOC_NOT_IN_QUOTA);
Josh Boyer 5e72ee3
+	if (IS_ERR(modsign_blacklist))
Josh Boyer 5e72ee3
+		panic("Can't allocate module signing blacklist keyring\n");
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	if (key_instantiate_and_link(modsign_blacklist, NULL, 0, NULL, NULL) < 0)
Josh Boyer 5e72ee3
+		panic("Can't instantiate module signing blacklist keyring\n");
Josh Boyer 5e72ee3
+#endif
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 	return 0;
Josh Boyer 5e72ee3
 }
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
diff --git a/kernel/module-internal.h b/kernel/module-internal.h
Josh Boyer 5e72ee3
index 24f9247..51a8380 100644
Josh Boyer 5e72ee3
--- a/kernel/module-internal.h
Josh Boyer 5e72ee3
+++ b/kernel/module-internal.h
Josh Boyer 5e72ee3
@@ -10,5 +10,8 @@
Josh Boyer 5e72ee3
  */
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 extern struct key *modsign_keyring;
Josh Boyer 5e72ee3
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
Josh Boyer 5e72ee3
+extern struct key *modsign_blacklist;
Josh Boyer 5e72ee3
+#endif
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 extern int mod_verify_sig(const void *mod, unsigned long *_modlen);
Josh Boyer 5e72ee3
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
Josh Boyer 5e72ee3
index ea1b1df..602aa24 100644
Josh Boyer 5e72ee3
--- a/kernel/module_signing.c
Josh Boyer 5e72ee3
+++ b/kernel/module_signing.c
Josh Boyer 5e72ee3
@@ -132,7 +132,7 @@ static int mod_extract_mpi_array(struct public_key_signature *pks,
Josh Boyer 5e72ee3
 static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
Josh Boyer 5e72ee3
 					  const u8 *key_id, size_t key_id_len)
Josh Boyer 5e72ee3
 {
Josh Boyer 5e72ee3
-	key_ref_t key;
Josh Boyer 5e72ee3
+	key_ref_t key, blacklist;
Josh Boyer 5e72ee3
 	size_t i;
Josh Boyer 5e72ee3
 	char *id, *q;
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
@@ -157,6 +157,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 	pr_debug("Look up: \"%s\"\n", id);
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
Josh Boyer 5e72ee3
+	blacklist = keyring_search(make_key_ref(modsign_blacklist, 1),
Josh Boyer 5e72ee3
+				   &key_type_asymmetric, id);
Josh Boyer 5e72ee3
+	if (!IS_ERR(blacklist)) {
Josh Boyer 5e72ee3
+		/* module is signed with a cert in the blacklist.  reject */
Josh Boyer 5e72ee3
+		pr_err("Module key '%s' is in blacklist\n", id);
Josh Boyer 23aad7f
+		key_ref_put(blacklist);
Josh Boyer 5e72ee3
+		kfree(id);
Josh Boyer 5e72ee3
+		return ERR_PTR(-EKEYREJECTED);
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+#endif
Josh Boyer 5e72ee3
+	
Josh Boyer 5e72ee3
 	key = keyring_search(make_key_ref(modsign_keyring, 1),
Josh Boyer 5e72ee3
 			     &key_type_asymmetric, id);
Josh Boyer 5e72ee3
 	if (IS_ERR(key))
Josh Boyer 5e72ee3
-- 
Josh Boyer 5e72ee3
1.7.12.1
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
From ddd5e2e1b775fb19aeec7fb842e707fc35347bc0 Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee3
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
Date: Fri, 26 Oct 2012 12:42:16 -0400
Josh Boyer 5e72ee3
Subject: [PATCH] MODSIGN: Import certificates from UEFI Secure Boot
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Secure Boot stores a list of allowed certificates in the 'db' variable.
Josh Boyer 5e72ee3
This imports those certificates into the module signing keyring.  This
Josh Boyer 5e72ee3
allows for a third party signing certificate to be used in conjunction
Josh Boyer 5e72ee3
with signed modules.  By importing the public certificate into the 'db'
Josh Boyer 5e72ee3
variable, a user can allow a module signed with that certificate to
Josh Boyer 5e72ee3
load.
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
In the opposite case, Secure Boot maintains a list of disallowed
Josh Boyer 5e72ee3
certificates in the 'dbx' variable.  We load those certificates into
Josh Boyer 5e72ee3
the newly introduced module blacklist keyring and forbid any module
Josh Boyer 5e72ee3
signed with those from loading.
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
---
Josh Boyer 5e72ee3
 include/linux/efi.h   |  3 ++
Josh Boyer 5e72ee3
 init/Kconfig          |  9 ++++++
Josh Boyer 5e72ee3
 kernel/Makefile       |  3 ++
Josh Boyer 5e72ee3
 kernel/modsign_uefi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++
Josh Boyer 5e72ee3
 4 files changed, 99 insertions(+)
Josh Boyer 5e72ee3
 create mode 100644 kernel/modsign_uefi.c
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer 5e72ee3
index ff72468..509755e 100644
Josh Boyer 5e72ee3
--- a/include/linux/efi.h
Josh Boyer 5e72ee3
+++ b/include/linux/efi.h
Josh Boyer 5e72ee3
@@ -318,6 +318,9 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
Josh Boyer 5e72ee3
 #define EFI_CERT_X509_GUID \
Josh Boyer 5e72ee3
     EFI_GUID(  0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 )
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+#define EFI_IMAGE_SECURITY_DATABASE_GUID \
Josh Boyer 5e72ee3
+    EFI_GUID(  0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f )
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 typedef struct {
Josh Boyer 5e72ee3
 	efi_guid_t guid;
Josh Boyer 5e72ee3
 	u64 table;
Josh Boyer 5e72ee3
diff --git a/init/Kconfig b/init/Kconfig
Josh Boyer 5e72ee3
index 7a9bf00..9c4c529 100644
Josh Boyer 5e72ee3
--- a/init/Kconfig
Josh Boyer 5e72ee3
+++ b/init/Kconfig
Josh Boyer 5e72ee3
@@ -1610,6 +1610,15 @@ config MODULE_SIG_BLACKLIST
Josh Boyer 5e72ee3
 	  should not pass module signature verification.  If a module is
Josh Boyer 5e72ee3
 	  signed with something in this keyring, the load will be rejected.
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+config MODULE_SIG_UEFI
Josh Boyer 5e72ee3
+	bool "Allow modules signed with certs stored in UEFI"
Josh Boyer 5e72ee3
+	depends on MODULE_SIG && MODULE_SIG_BLACKLIST && EFI
Josh Boyer 5e72ee3
+	select EFI_SIGNATURE_LIST_PARSER
Josh Boyer 5e72ee3
+	help
Josh Boyer 5e72ee3
+	  This will import certificates stored in UEFI and allow modules
Josh Boyer 5e72ee3
+	  signed with those to be loaded.  It will also disallow loading
Josh Boyer 5e72ee3
+	  of modules stored in the UEFI dbx variable.
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 choice
Josh Boyer 5e72ee3
 	prompt "Which hash algorithm should modules be signed with?"
Josh Boyer 5e72ee3
 	depends on MODULE_SIG
Josh Boyer 5e72ee3
diff --git a/kernel/Makefile b/kernel/Makefile
Josh Boyer 5e72ee3
index 0dfeca4..ff1468f 100644
Josh Boyer 5e72ee3
--- a/kernel/Makefile
Josh Boyer 5e72ee3
+++ b/kernel/Makefile
Josh Boyer 5e72ee3
@@ -55,6 +55,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
Josh Boyer 5e72ee3
 obj-$(CONFIG_UID16) += uid16.o
Josh Boyer 5e72ee3
 obj-$(CONFIG_MODULES) += module.o
Josh Boyer 5e72ee3
 obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o
Josh Boyer 5e72ee3
+obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o
Josh Boyer 5e72ee3
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
Josh Boyer 5e72ee3
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
Josh Boyer 5e72ee3
 obj-$(CONFIG_KEXEC) += kexec.o
Josh Boyer 5e72ee3
@@ -113,6 +114,8 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 $(obj)/configs.o: $(obj)/config_data.h
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+$(obj)/modsign_uefi.o: KBUILD_CFLAGS += -fshort-wchar
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 # config_data.h contains the same information as ikconfig.h but gzipped.
Josh Boyer 5e72ee3
 # Info from config_data can be extracted from /proc/config*
Josh Boyer 5e72ee3
 targets += config_data.gz
Josh Boyer 5e72ee3
diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c
Josh Boyer 5e72ee3
new file mode 100644
Josh Boyer 5e72ee3
index 0000000..049669d
Josh Boyer 5e72ee3
--- /dev/null
Josh Boyer 5e72ee3
+++ b/kernel/modsign_uefi.c
Josh Boyer 5e72ee3
@@ -0,0 +1,84 @@
Josh Boyer 5e72ee3
+#include <linux/kernel.h>
Josh Boyer 5e72ee3
+#include <linux/sched.h>
Josh Boyer 5e72ee3
+#include <linux/cred.h>
Josh Boyer 5e72ee3
+#include <linux/err.h>
Josh Boyer 5e72ee3
+#include <linux/efi.h>
Josh Boyer 5e72ee3
+#include <keys/asymmetric-type.h>
Josh Boyer 5e72ee3
+#include "module-internal.h"
Josh Boyer 5e72ee3
+
Josh Boyer 23aad7f
+static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size)
Josh Boyer 5e72ee3
+{
Josh Boyer 5e72ee3
+	efi_status_t status;
Josh Boyer 5e72ee3
+	unsigned long lsize = 4;
Josh Boyer 5e72ee3
+	unsigned long tmpdb[4];
Josh Boyer 5e72ee3
+	void *db = NULL;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
Josh Boyer 5e72ee3
+	if (status != EFI_BUFFER_TOO_SMALL) {
Josh Boyer 5e72ee3
+		pr_err("Couldn't get size: 0x%lx\n", status);
Josh Boyer 5e72ee3
+		return NULL;
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	db = kmalloc(lsize, GFP_KERNEL);
Josh Boyer 5e72ee3
+	if (!db) {
Josh Boyer 5e72ee3
+		pr_err("Couldn't allocate memory for uefi cert list\n");
Josh Boyer 5e72ee3
+		goto out;
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	status = efi.get_variable(name, guid, NULL, &lsize, db);
Josh Boyer 5e72ee3
+	if (status != EFI_SUCCESS) {
Josh Boyer 5e72ee3
+		kfree(db);
Josh Boyer 5e72ee3
+		db = NULL;
Josh Boyer 5e72ee3
+		pr_err("Error reading db var: 0x%lx\n", status);
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+out:
Josh Boyer 5e72ee3
+	*size = lsize;
Josh Boyer 5e72ee3
+	return db;
Josh Boyer 5e72ee3
+}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+/*
Josh Boyer 5e72ee3
+ *  * Load the certs contained in the UEFI databases
Josh Boyer 5e72ee3
+ *   */
Josh Boyer 5e72ee3
+static int __init load_uefi_certs(void)
Josh Boyer 5e72ee3
+{
Josh Boyer 5e72ee3
+	efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
Josh Boyer 5e72ee3
+	void *db = NULL, *dbx = NULL;
Josh Boyer 5e72ee3
+	unsigned long dbsize = 0, dbxsize = 0;
Josh Boyer 5e72ee3
+	int rc = 0;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	/* Check if SB is enabled and just return if not */
Josh Boyer 5e72ee3
+	if (!secure_boot_enabled)
Josh Boyer 5e72ee3
+		return 0;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	db = get_cert_list(L"db", &secure_var, &dbsize);
Josh Boyer 5e72ee3
+	if (!db) {
Josh Boyer 5e72ee3
+		pr_err("Couldn't get db list\n");
Josh Boyer 5e72ee3
+		rc = -1;
Josh Boyer 5e72ee3
+		goto err;
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	/* Get dbx.  It might not exist, so it isn't an error if we can't
Josh Boyer 5e72ee3
+	 * get it.
Josh Boyer 5e72ee3
+	 */
Josh Boyer 5e72ee3
+	dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
Josh Boyer 5e72ee3
+	if (!dbx) {
Josh Boyer 5e72ee3
+		pr_err("Couldn't get dbx list\n");
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	rc = parse_efi_signature_list(db, dbsize, modsign_keyring);
Josh Boyer 5e72ee3
+	if (rc)
Josh Boyer 5e72ee3
+		pr_err("Couldn't parse db signatures: %d\n", rc);
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+	if (dbx) {
Josh Boyer 5e72ee3
+		rc = parse_efi_signature_list(dbx, dbxsize,
Josh Boyer 5e72ee3
+			modsign_blacklist);
Josh Boyer 5e72ee3
+		if (rc)
Josh Boyer 5e72ee3
+			pr_err("Couldn't parse dbx signatures: %d\n", rc);
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
+err:
Josh Boyer 5e72ee3
+	kfree(db);
Josh Boyer 5e72ee3
+	kfree(dbx);
Josh Boyer 5e72ee3
+	return rc;
Josh Boyer 5e72ee3
+}
Josh Boyer 5e72ee3
+late_initcall(load_uefi_certs);
Josh Boyer 5e72ee3
-- 
Josh Boyer 5e72ee3
1.7.12.1
Josh Boyer 5e72ee3
Josh Boyer b07f543
Josh Boyer b07f543
From 924e09f1b267c407ca037171bc6f8f90b09265d6 Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee3
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
Date: Fri, 26 Oct 2012 14:02:09 -0400
Josh Boyer 5e72ee3
Subject: [PATCH] hibernate: Disable in a Secure Boot environment
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
There is currently no way to verify the resume image when returning
Josh Boyer 5e72ee3
from hibernate.  This might compromise the secure boot trust model,
Josh Boyer 5e72ee3
so until we can work with signed hibernate images we disable it in
Josh Boyer 5e72ee3
a Secure Boot environment.
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee3
---
Josh Boyer b07f543
 v2: Updated to include swsup after feedback from Jiri Kosina <jkosina@suse.cz>
Josh Boyer b07f543
Josh Boyer 5e72ee3
 kernel/power/hibernate.c | 14 +++++++++++++-
Josh Boyer 5e72ee3
 kernel/power/main.c      |  4 +++-
Josh Boyer b07f543
 kernel/power/user.c      |  3 +++
Josh Boyer b07f543
 3 files changed, 19 insertions(+), 2 deletions(-)
Josh Boyer 5e72ee3
Josh Boyer 5e72ee3
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
Josh Boyer 5e72ee3
index b26f5f1..f04343b 100644
Josh Boyer 5e72ee3
--- a/kernel/power/hibernate.c
Josh Boyer 5e72ee3
+++ b/kernel/power/hibernate.c
Josh Boyer 5e72ee3
@@ -632,6 +632,10 @@ int hibernate(void)
Josh Boyer 5e72ee3
 {
Josh Boyer 5e72ee3
 	int error;
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+	if (!capable(CAP_COMPROMISE_KERNEL)) {
Josh Boyer 5e72ee3
+		return -EPERM;
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 	lock_system_sleep();
Josh Boyer 5e72ee3
 	/* The snapshot device should not be opened while we're running */
Josh Boyer 5e72ee3
 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
Josh Boyer 5e72ee3
@@ -723,7 +727,7 @@ static int software_resume(void)
Josh Boyer 5e72ee3
 	/*
Josh Boyer 5e72ee3
 	 * If the user said "noresume".. bail out early.
Josh Boyer 5e72ee3
 	 */
Josh Boyer 5e72ee3
-	if (noresume)
Josh Boyer 5e72ee3
+	if (noresume || !capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 5e72ee3
 		return 0;
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
 	/*
Josh Boyer 5e72ee3
@@ -889,6 +893,11 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr,
Josh Boyer 5e72ee3
 	int i;
Josh Boyer 5e72ee3
 	char *start = buf;
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+	if (!capable(CAP_COMPROMISE_KERNEL)) {
Josh Boyer 5e72ee3
+		buf += sprintf(buf, "[%s]\n", "disabled");
Josh Boyer 5e72ee3
+		return buf-start;
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 	for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
Josh Boyer 5e72ee3
 		if (!hibernation_modes[i])
Josh Boyer 5e72ee3
 			continue;
Josh Boyer 5e72ee3
@@ -923,6 +932,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
Josh Boyer 5e72ee3
 	char *p;
Josh Boyer 5e72ee3
 	int mode = HIBERNATION_INVALID;
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 5e72ee3
+		return -EPERM;
Josh Boyer 5e72ee3
+
Josh Boyer 5e72ee3
 	p = memchr(buf, '\n', n);
Josh Boyer 5e72ee3
 	len = p ? p - buf : n;
Josh Boyer 5e72ee3
 
Josh Boyer 5e72ee3
diff --git a/kernel/power/main.c b/kernel/power/main.c
Josh Boyer 5e72ee3
index f458238..72580c1 100644
Josh Boyer 5e72ee3
--- a/kernel/power/main.c
Josh Boyer 5e72ee3
+++ b/kernel/power/main.c
Josh Boyer 5e72ee3
@@ -301,7 +301,9 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
Josh Boyer 5e72ee3
 	}
Josh Boyer 5e72ee3
 #endif
Josh Boyer 5e72ee3
 #ifdef CONFIG_HIBERNATION
Josh Boyer 5e72ee3
-	s += sprintf(s, "%s\n", "disk");
Josh Boyer 5e72ee3
+	if (capable(CAP_COMPROMISE_KERNEL)) {
Josh Boyer 5e72ee3
+		s += sprintf(s, "%s\n", "disk");
Josh Boyer 5e72ee3
+	}
Josh Boyer 5e72ee3
 #else
Josh Boyer 5e72ee3
 	if (s != buf)
Josh Boyer 5e72ee3
 		/* convert the last space to a newline */
Josh Boyer b07f543
diff --git a/kernel/power/user.c b/kernel/power/user.c
Josh Boyer b07f543
index 4ed81e7..b11a0f4 100644
Josh Boyer b07f543
--- a/kernel/power/user.c
Josh Boyer b07f543
+++ b/kernel/power/user.c
Josh Boyer b07f543
@@ -48,6 +48,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
Josh Boyer b07f543
 	struct snapshot_data *data;
Josh Boyer b07f543
 	int error;
Josh Boyer b07f543
 
Josh Boyer b07f543
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer b07f543
+		return -EPERM;
Josh Boyer b07f543
+
Josh Boyer b07f543
 	lock_system_sleep();
Josh Boyer b07f543
 
Josh Boyer b07f543
 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
Josh Boyer 5e72ee3
-- 
Josh Boyer 5e72ee3
1.7.12.1
Josh Boyer 5e72ee3