Josh Boyer b1b2d3
From 0c5837031a4e996877930fd023a5877dd1d615ba Mon Sep 17 00:00:00 2001
Josh Boyer 306dfc
From: Matthew Garrett <mjg@redhat.com>
Josh Boyer f0f4ff
Date: Thu, 20 Sep 2012 10:40:56 -0400
Josh Boyer b1b2d3
Subject: [PATCH 01/19] Secure boot: Add new capability
Josh Boyer 306dfc
Josh Boyer 306dfc
Secure boot adds certain policy requirements, including that root must not
Josh Boyer 306dfc
be able to do anything that could cause the kernel to execute arbitrary code.
Josh Boyer 306dfc
The simplest way to handle this would seem to be to add a new capability
Josh Boyer 306dfc
and gate various functionality on that. We'll then strip it from the initial
Josh Boyer 306dfc
capability set if required.
Josh Boyer 306dfc
Josh Boyer 306dfc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 306dfc
---
be7ac5
 include/uapi/linux/capability.h | 6 +++++-
Josh Boyer 306dfc
 1 file changed, 5 insertions(+), 1 deletion(-)
Josh Boyer 306dfc
Josh Boyer 4fc17c
diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
Josh Boyer 4fc17c
index ba478fa..7109e65 100644
be7ac5
--- a/include/uapi/linux/capability.h
be7ac5
+++ b/include/uapi/linux/capability.h
Josh Boyer 4fc17c
@@ -343,7 +343,11 @@ struct vfs_cap_data {
Josh Boyer 306dfc
 
Josh Boyer 306dfc
 #define CAP_BLOCK_SUSPEND    36
Josh Boyer 306dfc
 
Josh Boyer 306dfc
-#define CAP_LAST_CAP         CAP_BLOCK_SUSPEND
Josh Boyer f0f4ff
+/* Allow things that trivially permit root to modify the running kernel */
Josh Boyer 306dfc
+
Josh Boyer f0f4ff
+#define CAP_COMPROMISE_KERNEL  37
Josh Boyer 306dfc
+
Josh Boyer f0f4ff
+#define CAP_LAST_CAP         CAP_COMPROMISE_KERNEL
Josh Boyer 306dfc
 
Josh Boyer 306dfc
 #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
Josh Boyer 306dfc
 
Josh Boyer 306dfc
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 306dfc
Josh Boyer 306dfc
Josh Boyer b1b2d3
From 87c8fddbcb3042fc4174b53763adbf66045a12be Mon Sep 17 00:00:00 2001
f82b10
From: Josh Boyer <jwboyer@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:41:05 -0400
Josh Boyer b1b2d3
Subject: [PATCH 02/19] SELinux: define mapping for new Secure Boot capability
Josh Boyer 306dfc
f82b10
Add the name of the new Secure Boot capability.  This allows SELinux
f82b10
policies to properly map CAP_COMPROMISE_KERNEL to the appropriate
f82b10
capability class.
Josh Boyer 306dfc
f82b10
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 306dfc
---
f82b10
 security/selinux/include/classmap.h | 4 ++--
f82b10
 1 file changed, 2 insertions(+), 2 deletions(-)
Josh Boyer 306dfc
f82b10
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
Josh Boyer 47a1eb
index 14d04e6..ed99a2d 100644
f82b10
--- a/security/selinux/include/classmap.h
f82b10
+++ b/security/selinux/include/classmap.h
f82b10
@@ -146,8 +146,8 @@ struct security_class_mapping secclass_map[] = {
f82b10
 	{ "memprotect", { "mmap_zero", NULL } },
f82b10
 	{ "peer", { "recv", NULL } },
f82b10
 	{ "capability2",
f82b10
-	  { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend",
f82b10
-	    NULL } },
f82b10
+	  { "mac_override", "mac_admin", "syslog", "wake_alarm",
f82b10
+	    "block_suspend", "compromise_kernel", NULL } },
f82b10
 	{ "kernel_service", { "use_as_override", "create_files_as", NULL } },
f82b10
 	{ "tun_socket",
Josh Boyer 47a1eb
 	  { COMMON_SOCK_PERMS, "attach_queue", NULL } },
Josh Boyer 306dfc
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 306dfc
Josh Boyer 306dfc
Josh Boyer b1b2d3
From df14b5319bf3ed2110839e233ac61e6136745be8 Mon Sep 17 00:00:00 2001
f82b10
From: Josh Boyer <jwboyer@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:41:02 -0400
Josh Boyer b1b2d3
Subject: [PATCH 03/19] Secure boot: Add a dummy kernel parameter that will
f82b10
 switch on Secure Boot mode
Josh Boyer 306dfc
f82b10
This forcibly drops CAP_COMPROMISE_KERNEL from both cap_permitted and cap_bset
f82b10
in the init_cred struct, which everything else inherits from.  This works on
f82b10
any machine and can be used to develop even if the box doesn't have UEFI.
Josh Boyer 306dfc
f82b10
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 306dfc
---
f82b10
 Documentation/kernel-parameters.txt |  7 +++++++
f82b10
 kernel/cred.c                       | 17 +++++++++++++++++
f82b10
 2 files changed, 24 insertions(+)
Josh Boyer 306dfc
f82b10
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
Josh Boyer b1b2d3
index 6c72381..7dffdd5 100644
f82b10
--- a/Documentation/kernel-parameters.txt
f82b10
+++ b/Documentation/kernel-parameters.txt
f82b10
@@ -2654,6 +2654,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
f82b10
 			Note: increases power consumption, thus should only be
f82b10
 			enabled if running jitter sensitive (HPC/RT) workloads.
Josh Boyer 306dfc
 
f82b10
+	secureboot_enable=
f82b10
+			[KNL] Enables an emulated UEFI Secure Boot mode.  This
f82b10
+			locks down various aspects of the kernel guarded by the
f82b10
+			CAP_COMPROMISE_KERNEL capability.  This includes things
f82b10
+			like /dev/mem, IO port access, and other areas.  It can
f82b10
+			be used on non-UEFI machines for testing purposes.
f82b10
+
f82b10
 	security=	[SECURITY] Choose a security module to enable at boot.
f82b10
 			If this boot parameter is not specified, only the first
f82b10
 			security module asking for security registration will be
f82b10
diff --git a/kernel/cred.c b/kernel/cred.c
f82b10
index e0573a4..c3f4e3e 100644
f82b10
--- a/kernel/cred.c
f82b10
+++ b/kernel/cred.c
f82b10
@@ -565,6 +565,23 @@ void __init cred_init(void)
f82b10
 				     0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
f82b10
 }
Josh Boyer 306dfc
 
f82b10
+void __init secureboot_enable()
f82b10
+{
f82b10
+	pr_info("Secure boot enabled\n");
f82b10
+	cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL);
f82b10
+	cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL);
f82b10
+}
Josh Boyer 306dfc
+
f82b10
+/* Dummy Secure Boot enable option to fake out UEFI SB=1 */
f82b10
+static int __init secureboot_enable_opt(char *str)
f82b10
+{
f82b10
+	int sb_enable = !!simple_strtol(str, NULL, 0);
f82b10
+	if (sb_enable)
f82b10
+		secureboot_enable();
f82b10
+	return 1;
f82b10
+}
f82b10
+__setup("secureboot_enable=", secureboot_enable_opt);
f82b10
+
f82b10
 /**
f82b10
  * prepare_kernel_cred - Prepare a set of credentials for a kernel service
f82b10
  * @daemon: A userspace daemon to be used as a reference
Josh Boyer 306dfc
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 306dfc
Josh Boyer 306dfc
Josh Boyer b1b2d3
From 49c76a665e8a09da48cbe271ea40266ca1a226c0 Mon Sep 17 00:00:00 2001
Josh Boyer 306dfc
From: Matthew Garrett <mjg@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:41:03 -0400
Josh Boyer b1b2d3
Subject: [PATCH 04/19] efi: Enable secure boot lockdown automatically when
f82b10
 enabled in firmware
Josh Boyer 306dfc
f82b10
The firmware has a set of flags that indicate whether secure boot is enabled
f82b10
and enforcing. Use them to indicate whether the kernel should lock itself
Josh Boyer a8e5ae
down.  We also indicate the machine is in secure boot mode by adding the
Josh Boyer a8e5ae
EFI_SECURE_BOOT bit for use with efi_enabled.
Josh Boyer 306dfc
Josh Boyer 306dfc
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer a8e5ae
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 306dfc
---
f82b10
 Documentation/x86/zero-page.txt       |  2 ++
f82b10
 arch/x86/boot/compressed/eboot.c      | 32 ++++++++++++++++++++++++++++++++
f82b10
 arch/x86/include/uapi/asm/bootparam.h |  3 ++-
Josh Boyer b1b2d3
 arch/x86/kernel/setup.c               |  7 +++++++
f82b10
 include/linux/cred.h                  |  2 ++
Josh Boyer a8e5ae
 include/linux/efi.h                   |  1 +
Josh Boyer b1b2d3
 6 files changed, 46 insertions(+), 1 deletion(-)
Josh Boyer 306dfc
f82b10
diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
Josh Boyer 47a1eb
index 199f453..ff651d3 100644
f82b10
--- a/Documentation/x86/zero-page.txt
f82b10
+++ b/Documentation/x86/zero-page.txt
Josh Boyer 47a1eb
@@ -30,6 +30,8 @@ Offset	Proto	Name		Meaning
f82b10
 1E9/001	ALL	eddbuf_entries	Number of entries in eddbuf (below)
f82b10
 1EA/001	ALL	edd_mbr_sig_buf_entries	Number of entries in edd_mbr_sig_buffer
f82b10
 				(below)
f82b10
+1EB/001	ALL	kbd_status	Numlock is enabled
f82b10
+1EC/001	ALL	secure_boot	Kernel should enable secure boot lockdowns
Josh Boyer 47a1eb
 1EF/001	ALL	sentinel	Used to detect broken bootloaders
f82b10
 290/040	ALL	edd_mbr_sig_buffer EDD MBR signatures
f82b10
 2D0/A00	ALL	e820_map	E820 memory map table
f82b10
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
Josh Boyer 47a1eb
index f8fa411..96bd86b 100644
f82b10
--- a/arch/x86/boot/compressed/eboot.c
f82b10
+++ b/arch/x86/boot/compressed/eboot.c
Josh Boyer 47a1eb
@@ -849,6 +849,36 @@ fail:
f82b10
 	return status;
f82b10
 }
Josh Boyer 306dfc
 
f82b10
+static int get_secure_boot(efi_system_table_t *_table)
f82b10
+{
f82b10
+	u8 sb, setup;
f82b10
+	unsigned long datasize = sizeof(sb);
f82b10
+	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
f82b10
+	efi_status_t status;
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+	status = efi_call_phys5(sys_table->runtime->get_variable,
Josh Boyer 306dfc
+				L"SecureBoot", &var_guid, NULL, &datasize, &sb);
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+	if (status != EFI_SUCCESS)
Josh Boyer 306dfc
+		return 0;
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+	if (sb == 0)
Josh Boyer 306dfc
+		return 0;
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+	status = efi_call_phys5(sys_table->runtime->get_variable,
Josh Boyer 306dfc
+				L"SetupMode", &var_guid, NULL, &datasize,
Josh Boyer 306dfc
+				&setup);
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+	if (status != EFI_SUCCESS)
Josh Boyer 306dfc
+		return 0;
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+	if (setup == 1)
Josh Boyer 306dfc
+		return 0;
Josh Boyer 306dfc
+
Josh Boyer 306dfc
+	return 1;
Josh Boyer 306dfc
+}
Josh Boyer 306dfc
+
Josh Boyer 306dfc
 /*
Josh Boyer 306dfc
  * Because the x86 boot code expects to be passed a boot_params we
Josh Boyer 306dfc
  * need to create one ourselves (usually the bootloader would create
Josh Boyer 47a1eb
@@ -1143,6 +1173,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
Josh Boyer 306dfc
 	if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
Josh Boyer 306dfc
 		goto fail;
Josh Boyer 306dfc
 
Josh Boyer 306dfc
+	boot_params->secure_boot = get_secure_boot(sys_table);
Josh Boyer 306dfc
+
Josh Boyer 306dfc
 	setup_graphics(boot_params);
Josh Boyer 306dfc
 
f82b10
 	setup_efi_pci(boot_params);
f82b10
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
Josh Boyer 47a1eb
index c15ddaf..85d7685 100644
f82b10
--- a/arch/x86/include/uapi/asm/bootparam.h
f82b10
+++ b/arch/x86/include/uapi/asm/bootparam.h
Josh Boyer 47a1eb
@@ -131,7 +131,8 @@ struct boot_params {
Josh Boyer 306dfc
 	__u8  eddbuf_entries;				/* 0x1e9 */
Josh Boyer 306dfc
 	__u8  edd_mbr_sig_buf_entries;			/* 0x1ea */
Josh Boyer 306dfc
 	__u8  kbd_status;				/* 0x1eb */
Josh Boyer 47a1eb
-	__u8  _pad5[3];					/* 0x1ec */
Josh Boyer 306dfc
+	__u8  secure_boot;				/* 0x1ec */
Josh Boyer 47a1eb
+	__u8  _pad5[2];					/* 0x1ed */
Josh Boyer 47a1eb
 	/*
Josh Boyer 47a1eb
 	 * The sentinel is set to a nonzero value (0xff) in header.S.
Josh Boyer 47a1eb
 	 *
Josh Boyer 306dfc
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
Josh Boyer b1b2d3
index 8b24289..d74b441 100644
Josh Boyer 306dfc
--- a/arch/x86/kernel/setup.c
Josh Boyer 306dfc
+++ b/arch/x86/kernel/setup.c
Josh Boyer b1b2d3
@@ -1042,6 +1042,13 @@ void __init setup_arch(char **cmdline_p)
Josh Boyer 306dfc
 
Josh Boyer 306dfc
 	io_delay_init();
Josh Boyer 306dfc
 
Josh Boyer a8e5ae
+	if (boot_params.secure_boot) {
Josh Boyer b1b2d3
+#ifdef CONFIG_EFI
Josh Boyer a8e5ae
+		set_bit(EFI_SECURE_BOOT, &x86_efi_facility);
Josh Boyer b1b2d3
+#endif
Josh Boyer 306dfc
+		secureboot_enable();
Josh Boyer a8e5ae
+	}
Josh Boyer 306dfc
+
Josh Boyer 306dfc
 	/*
Josh Boyer 306dfc
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
Josh Boyer 306dfc
 	 */
Josh Boyer 306dfc
diff --git a/include/linux/cred.h b/include/linux/cred.h
Josh Boyer 95c664
index 04421e8..9e69542 100644
Josh Boyer 306dfc
--- a/include/linux/cred.h
Josh Boyer 306dfc
+++ b/include/linux/cred.h
Josh Boyer 95c664
@@ -156,6 +156,8 @@ extern int set_security_override_from_ctx(struct cred *, const char *);
Josh Boyer 306dfc
 extern int set_create_files_as(struct cred *, struct inode *);
Josh Boyer 306dfc
 extern void __init cred_init(void);
Josh Boyer 306dfc
 
Josh Boyer 306dfc
+extern void secureboot_enable(void);
Josh Boyer 306dfc
+
Josh Boyer 306dfc
 /*
Josh Boyer 306dfc
  * check for validity of credentials
Josh Boyer 306dfc
  */
f82b10
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer a8e5ae
index 7a9498a..1ae16b6 100644
f82b10
--- a/include/linux/efi.h
f82b10
+++ b/include/linux/efi.h
Josh Boyer a8e5ae
@@ -627,6 +627,7 @@ extern int __init efi_setup_pcdp_console(char *);
Josh Boyer a8e5ae
 #define EFI_RUNTIME_SERVICES	3	/* Can we use runtime services? */
Josh Boyer a8e5ae
 #define EFI_MEMMAP		4	/* Can we use EFI memory map? */
Josh Boyer a8e5ae
 #define EFI_64BIT		5	/* Is the firmware 64-bit? */
Josh Boyer a8e5ae
+#define EFI_SECURE_BOOT	6	/* Are we in Secure Boot mode? */
Josh Boyer 306dfc
 
Josh Boyer a8e5ae
 #ifdef CONFIG_EFI
Josh Boyer a8e5ae
 # ifdef CONFIG_X86
Josh Boyer 306dfc
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer f0f4ff
Josh Boyer f0f4ff
Josh Boyer b1b2d3
From d4d1b3ad3e1a553c807b4ecafcbde4bf816e4db2 Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee
From: Dave Howells <dhowells@redhat.com>
Josh Boyer 5e72ee
Date: Tue, 23 Oct 2012 09:30:54 -0400
Josh Boyer b1b2d3
Subject: [PATCH 05/19] Add EFI signature data types
f82b10
f82b10
Add the data types that are used for containing hashes, keys and certificates
f82b10
for cryptographic verification.
Josh Boyer 5e72ee
Josh Boyer 5e72ee
Signed-off-by: David Howells <dhowells@redhat.com>
Josh Boyer 5e72ee
---
Josh Boyer 5e72ee
 include/linux/efi.h | 20 ++++++++++++++++++++
Josh Boyer 5e72ee
 1 file changed, 20 insertions(+)
Josh Boyer 5e72ee
Josh Boyer 5e72ee
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer a8e5ae
index 1ae16b6..de7021d 100644
Josh Boyer 5e72ee
--- a/include/linux/efi.h
Josh Boyer 5e72ee
+++ b/include/linux/efi.h
f82b10
@@ -388,6 +388,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
Josh Boyer 5e72ee
 #define EFI_FILE_SYSTEM_GUID \
Josh Boyer 5e72ee
     EFI_GUID(  0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b )
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
+#define EFI_CERT_SHA256_GUID \
Josh Boyer 5e72ee
+    EFI_GUID(  0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 )
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+#define EFI_CERT_X509_GUID \
Josh Boyer 5e72ee
+    EFI_GUID(  0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 )
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
 typedef struct {
Josh Boyer 5e72ee
 	efi_guid_t guid;
Josh Boyer 5e72ee
 	u64 table;
f82b10
@@ -523,6 +529,20 @@ typedef struct {
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
 #define EFI_INVALID_TABLE_ADDR		(~0UL)
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
+typedef struct  {
Josh Boyer 5e72ee
+	efi_guid_t signature_owner;
Josh Boyer 5e72ee
+	u8 signature_data[];
Josh Boyer 5e72ee
+} efi_signature_data_t;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+typedef struct {
Josh Boyer 5e72ee
+	efi_guid_t signature_type;
Josh Boyer 5e72ee
+	u32 signature_list_size;
Josh Boyer 5e72ee
+	u32 signature_header_size;
Josh Boyer 5e72ee
+	u32 signature_size;
Josh Boyer 5e72ee
+	u8 signature_header[];
Josh Boyer 5e72ee
+	/* efi_signature_data_t signatures[][] */
Josh Boyer 5e72ee
+} efi_signature_list_t;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
 /*
Josh Boyer 5e72ee
  * All runtime access to EFI goes through this structure:
Josh Boyer 5e72ee
  */
Josh Boyer 5e72ee
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 5e72ee
Josh Boyer 5e72ee
Josh Boyer b1b2d3
From 3cffca89eadf7e0f0a266c370f8034f33723831a Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee
From: Dave Howells <dhowells@redhat.com>
Josh Boyer 5e72ee
Date: Tue, 23 Oct 2012 09:36:28 -0400
Josh Boyer b1b2d3
Subject: [PATCH 06/19] Add an EFI signature blob parser and key loader.
f82b10
f82b10
X.509 certificates are loaded into the specified keyring as asymmetric type
f82b10
keys.
Josh Boyer 5e72ee
Josh Boyer 5e72ee
Signed-off-by: David Howells <dhowells@redhat.com>
Josh Boyer 5e72ee
---
Josh Boyer 95c664
 crypto/asymmetric_keys/Kconfig      |   8 +++
Josh Boyer 5e72ee
 crypto/asymmetric_keys/Makefile     |   1 +
Josh Boyer 95c664
 crypto/asymmetric_keys/efi_parser.c | 108 ++++++++++++++++++++++++++++++++++++
Josh Boyer 5e72ee
 include/linux/efi.h                 |   4 ++
Josh Boyer 95c664
 4 files changed, 121 insertions(+)
Josh Boyer 5e72ee
 create mode 100644 crypto/asymmetric_keys/efi_parser.c
Josh Boyer 5e72ee
Josh Boyer 5e72ee
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
Josh Boyer 95c664
index 6d2c2ea..ace9c30 100644
Josh Boyer 5e72ee
--- a/crypto/asymmetric_keys/Kconfig
Josh Boyer 5e72ee
+++ b/crypto/asymmetric_keys/Kconfig
Josh Boyer 95c664
@@ -35,4 +35,12 @@ config X509_CERTIFICATE_PARSER
Josh Boyer 5e72ee
 	  data and provides the ability to instantiate a crypto key from a
Josh Boyer 5e72ee
 	  public key packet found inside the certificate.
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
+config EFI_SIGNATURE_LIST_PARSER
Josh Boyer 5e72ee
+	bool "EFI signature list parser"
Josh Boyer 95c664
+	depends on EFI
Josh Boyer 5e72ee
+	select X509_CERTIFICATE_PARSER
Josh Boyer 5e72ee
+	help
Josh Boyer 5e72ee
+	  This option provides support for parsing EFI signature lists for
Josh Boyer 5e72ee
+	  X.509 certificates and turning them into keys.
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
 endif # ASYMMETRIC_KEY_TYPE
Josh Boyer 5e72ee
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
Josh Boyer 5e72ee
index 0727204..cd8388e 100644
Josh Boyer 5e72ee
--- a/crypto/asymmetric_keys/Makefile
Josh Boyer 5e72ee
+++ b/crypto/asymmetric_keys/Makefile
Josh Boyer 5e72ee
@@ -8,6 +8,7 @@ asymmetric_keys-y := asymmetric_type.o signature.o
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
 obj-$(CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE) += public_key.o
Josh Boyer 5e72ee
 obj-$(CONFIG_PUBLIC_KEY_ALGO_RSA) += rsa.o
Josh Boyer 5e72ee
+obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
 #
Josh Boyer 5e72ee
 # X.509 Certificate handling
Josh Boyer 5e72ee
diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c
Josh Boyer 5e72ee
new file mode 100644
Josh Boyer 95c664
index 0000000..636feb1
Josh Boyer 5e72ee
--- /dev/null
Josh Boyer 5e72ee
+++ b/crypto/asymmetric_keys/efi_parser.c
Josh Boyer 95c664
@@ -0,0 +1,108 @@
Josh Boyer 5e72ee
+/* EFI signature/key/certificate list parser
Josh Boyer 5e72ee
+ *
Josh Boyer 5e72ee
+ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
Josh Boyer 5e72ee
+ * Written by David Howells (dhowells@redhat.com)
Josh Boyer 5e72ee
+ *
Josh Boyer 5e72ee
+ * This program is free software; you can redistribute it and/or
Josh Boyer 5e72ee
+ * modify it under the terms of the GNU General Public Licence
Josh Boyer 5e72ee
+ * as published by the Free Software Foundation; either version
Josh Boyer 5e72ee
+ * 2 of the Licence, or (at your option) any later version.
Josh Boyer 5e72ee
+ */
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+#define pr_fmt(fmt) "EFI: "fmt
Josh Boyer 5e72ee
+#include <linux/module.h>
Josh Boyer 5e72ee
+#include <linux/printk.h>
Josh Boyer 5e72ee
+#include <linux/err.h>
Josh Boyer 5e72ee
+#include <linux/efi.h>
Josh Boyer 5e72ee
+#include <keys/asymmetric-type.h>
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+/**
Josh Boyer 5e72ee
+ * parse_efi_signature_list - Parse an EFI signature list for certificates
Josh Boyer 5e72ee
+ * @data: The data blob to parse
Josh Boyer 5e72ee
+ * @size: The size of the data blob
Josh Boyer 5e72ee
+ * @keyring: The keyring to add extracted keys to
Josh Boyer 5e72ee
+ */
Josh Boyer 5e72ee
+int __init parse_efi_signature_list(const void *data, size_t size, struct key *keyring)
Josh Boyer 5e72ee
+{
Josh Boyer 5e72ee
+	unsigned offs = 0;
Josh Boyer 5e72ee
+	size_t lsize, esize, hsize, elsize;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+	pr_devel("-->%s(,%zu)\n", __func__, size);
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+	while (size > 0) {
Josh Boyer 5e72ee
+		efi_signature_list_t list;
Josh Boyer 5e72ee
+		const efi_signature_data_t *elem;
Josh Boyer 5e72ee
+		key_ref_t key;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+		if (size < sizeof(list))
Josh Boyer 5e72ee
+			return -EBADMSG;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+		memcpy(&list, data, sizeof(list));
Josh Boyer 5e72ee
+		pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n",
Josh Boyer 5e72ee
+			 offs,
Josh Boyer 5e72ee
+			 list.signature_type.b, list.signature_list_size,
Josh Boyer 5e72ee
+			 list.signature_header_size, list.signature_size);
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+		lsize = list.signature_list_size;
Josh Boyer 5e72ee
+		hsize = list.signature_header_size;
Josh Boyer 5e72ee
+		esize = list.signature_size;
Josh Boyer 5e72ee
+		elsize = lsize - sizeof(list) - hsize;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+		if (lsize > size) {
Josh Boyer 5e72ee
+			pr_devel("<--%s() = -EBADMSG [overrun @%x]\n",
Josh Boyer 5e72ee
+				 __func__, offs);
Josh Boyer 5e72ee
+			return -EBADMSG;
Josh Boyer 5e72ee
+		}
Josh Boyer 5e72ee
+		if (lsize < sizeof(list) ||
Josh Boyer 5e72ee
+		    lsize - sizeof(list) < hsize ||
Josh Boyer 5e72ee
+		    esize < sizeof(*elem) ||
Josh Boyer 5e72ee
+		    elsize < esize ||
Josh Boyer 5e72ee
+		    elsize % esize != 0) {
Josh Boyer 5e72ee
+			pr_devel("- bad size combo @%x\n", offs);
f82b10
+			return -EBADMSG;
Josh Boyer 5e72ee
+		}
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+		if (efi_guidcmp(list.signature_type, efi_cert_x509_guid) != 0) {
Josh Boyer 5e72ee
+			data += lsize;
Josh Boyer 5e72ee
+			size -= lsize;
Josh Boyer 5e72ee
+			offs += lsize;
Josh Boyer 5e72ee
+			continue;
Josh Boyer 5e72ee
+		}
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+		data += sizeof(list) + hsize;
Josh Boyer 5e72ee
+		size -= sizeof(list) + hsize;
Josh Boyer 5e72ee
+		offs += sizeof(list) + hsize;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+		for (; elsize > 0; elsize -= esize) {
Josh Boyer 5e72ee
+			elem = data;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+			pr_devel("ELEM[%04x]\n", offs);
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+			key = key_create_or_update(
Josh Boyer 5e72ee
+				make_key_ref(keyring, 1),
Josh Boyer 5e72ee
+				"asymmetric",
Josh Boyer 5e72ee
+				NULL,
Josh Boyer 5e72ee
+				&elem->signature_data,
Josh Boyer 5e72ee
+				esize - sizeof(*elem),
Josh Boyer 5e72ee
+				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
Josh Boyer 5e72ee
+				KEY_USR_VIEW,
Josh Boyer 5e72ee
+				KEY_ALLOC_NOT_IN_QUOTA);
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+			if (IS_ERR(key))
Josh Boyer 5e72ee
+				pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
Josh Boyer 5e72ee
+				       PTR_ERR(key));
Josh Boyer 5e72ee
+			else
Josh Boyer 95c664
+				pr_notice("Loaded cert '%s' linked to '%s'\n",
Josh Boyer 95c664
+					  key_ref_to_ptr(key)->description,
Josh Boyer 95c664
+					  keyring->description);
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+			data += esize;
Josh Boyer 5e72ee
+			size -= esize;
Josh Boyer 5e72ee
+			offs += esize;
Josh Boyer 5e72ee
+		}
Josh Boyer 5e72ee
+	}
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
+	return 0;
Josh Boyer 5e72ee
+}
Josh Boyer 5e72ee
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer a8e5ae
index de7021d..64b3e55 100644
Josh Boyer 5e72ee
--- a/include/linux/efi.h
Josh Boyer 5e72ee
+++ b/include/linux/efi.h
f82b10
@@ -612,6 +612,10 @@ extern int efi_set_rtc_mmss(unsigned long nowtime);
Josh Boyer 5e72ee
 extern void efi_reserve_boot_services(void);
Josh Boyer 5e72ee
 extern struct efi_memory_map memmap;
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
+struct key;
Josh Boyer 5e72ee
+extern int __init parse_efi_signature_list(const void *data, size_t size,
Josh Boyer 5e72ee
+					   struct key *keyring);
Josh Boyer 5e72ee
+
f82b10
 /**
f82b10
  * efi_range_is_wc - check the WC bit on an address range
f82b10
  * @start: starting kvirt address
f82b10
-- 
Josh Boyer b1b2d3
1.8.1.2
f82b10
f82b10
Josh Boyer b1b2d3
From 89ea7424726ae4f7265ab84e703cf2da77acda57 Mon Sep 17 00:00:00 2001
f82b10
From: Josh Boyer <jwboyer@redhat.com>
f82b10
Date: Fri, 26 Oct 2012 12:36:24 -0400
Josh Boyer b1b2d3
Subject: [PATCH 07/19] MODSIGN: Add module certificate blacklist keyring
f82b10
f82b10
This adds an additional keyring that is used to store certificates that
f82b10
are blacklisted.  This keyring is searched first when loading signed modules
f82b10
and if the module's certificate is found, it will refuse to load.  This is
f82b10
useful in cases where third party certificates are used for module signing.
f82b10
f82b10
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
f82b10
---
f82b10
 init/Kconfig             |  8 ++++++++
f82b10
 kernel/modsign_pubkey.c  | 14 ++++++++++++++
f82b10
 kernel/module-internal.h |  3 +++
Josh Boyer 95c664
 kernel/module_signing.c  | 12 ++++++++++++
Josh Boyer 95c664
 4 files changed, 37 insertions(+)
f82b10
f82b10
diff --git a/init/Kconfig b/init/Kconfig
Josh Boyer a8e5ae
index be8b7f5..d972b77 100644
f82b10
--- a/init/Kconfig
f82b10
+++ b/init/Kconfig
f82b10
@@ -1665,6 +1665,14 @@ config MODULE_SIG_FORCE
f82b10
 	  Reject unsigned modules or signed modules for which we don't have a
f82b10
 	  key.  Without this, such modules will simply taint the kernel.
f82b10
 
f82b10
+config MODULE_SIG_BLACKLIST
f82b10
+	bool "Support for blacklisting module signature certificates"
f82b10
+	depends on MODULE_SIG
f82b10
+	help
f82b10
+	  This adds support for keeping a blacklist of certificates that
f82b10
+	  should not pass module signature verification.  If a module is
f82b10
+	  signed with something in this keyring, the load will be rejected.
f82b10
+
f82b10
 choice
f82b10
 	prompt "Which hash algorithm should modules be signed with?"
f82b10
 	depends on MODULE_SIG
f82b10
diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
f82b10
index 2b6e699..4cd408d 100644
f82b10
--- a/kernel/modsign_pubkey.c
f82b10
+++ b/kernel/modsign_pubkey.c
f82b10
@@ -17,6 +17,9 @@
f82b10
 #include "module-internal.h"
f82b10
 
f82b10
 struct key *modsign_keyring;
f82b10
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
f82b10
+struct key *modsign_blacklist;
f82b10
+#endif
f82b10
 
f82b10
 extern __initdata const u8 modsign_certificate_list[];
f82b10
 extern __initdata const u8 modsign_certificate_list_end[];
f82b10
@@ -43,6 +46,17 @@ static __init int module_verify_init(void)
f82b10
 	if (IS_ERR(modsign_keyring))
f82b10
 		panic("Can't allocate module signing keyring\n");
f82b10
 
f82b10
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
f82b10
+	modsign_blacklist = keyring_alloc(".modsign_blacklist",
f82b10
+				    KUIDT_INIT(0), KGIDT_INIT(0),
f82b10
+				    current_cred(),
f82b10
+				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
f82b10
+				    KEY_USR_VIEW | KEY_USR_READ,
f82b10
+				    KEY_ALLOC_NOT_IN_QUOTA, NULL);
f82b10
+	if (IS_ERR(modsign_blacklist))
f82b10
+		panic("Can't allocate module signing blacklist keyring\n");
f82b10
+#endif
f82b10
+
f82b10
 	return 0;
f82b10
 }
f82b10
 
f82b10
diff --git a/kernel/module-internal.h b/kernel/module-internal.h
f82b10
index 24f9247..51a8380 100644
f82b10
--- a/kernel/module-internal.h
f82b10
+++ b/kernel/module-internal.h
f82b10
@@ -10,5 +10,8 @@
f82b10
  */
f82b10
 
f82b10
 extern struct key *modsign_keyring;
f82b10
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
f82b10
+extern struct key *modsign_blacklist;
f82b10
+#endif
f82b10
 
f82b10
 extern int mod_verify_sig(const void *mod, unsigned long *_modlen);
f82b10
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
Josh Boyer 95c664
index f2970bd..5423195 100644
f82b10
--- a/kernel/module_signing.c
f82b10
+++ b/kernel/module_signing.c
f82b10
@@ -157,6 +157,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
f82b10
 
f82b10
 	pr_debug("Look up: \"%s\"\n", id);
f82b10
 
f82b10
+#ifdef CONFIG_MODULE_SIG_BLACKLIST
Josh Boyer 95c664
+	key = keyring_search(make_key_ref(modsign_blacklist, 1),
f82b10
+				   &key_type_asymmetric, id);
Josh Boyer 95c664
+	if (!IS_ERR(key)) {
f82b10
+		/* module is signed with a cert in the blacklist.  reject */
f82b10
+		pr_err("Module key '%s' is in blacklist\n", id);
Josh Boyer 95c664
+		key_ref_put(key);
f82b10
+		kfree(id);
f82b10
+		return ERR_PTR(-EKEYREJECTED);
f82b10
+	}
f82b10
+#endif
f82b10
+
f82b10
 	key = keyring_search(make_key_ref(modsign_keyring, 1),
f82b10
 			     &key_type_asymmetric, id);
f82b10
 	if (IS_ERR(key))
f82b10
-- 
Josh Boyer b1b2d3
1.8.1.2
f82b10
f82b10
Josh Boyer b1b2d3
From 733a5c25b896d8d5fa0051825a671911b50cb47d Mon Sep 17 00:00:00 2001
f82b10
From: Josh Boyer <jwboyer@redhat.com>
f82b10
Date: Fri, 26 Oct 2012 12:42:16 -0400
Josh Boyer b1b2d3
Subject: [PATCH 08/19] MODSIGN: Import certificates from UEFI Secure Boot
f82b10
f82b10
Secure Boot stores a list of allowed certificates in the 'db' variable.
f82b10
This imports those certificates into the module signing keyring.  This
f82b10
allows for a third party signing certificate to be used in conjunction
f82b10
with signed modules.  By importing the public certificate into the 'db'
f82b10
variable, a user can allow a module signed with that certificate to
f82b10
load.  The shim UEFI bootloader has a similar certificate list stored
f82b10
in the 'MokListRT' variable.  We import those as well.
f82b10
f82b10
In the opposite case, Secure Boot maintains a list of disallowed
f82b10
certificates in the 'dbx' variable.  We load those certificates into
f82b10
the newly introduced module blacklist keyring and forbid any module
f82b10
signed with those from loading.
f82b10
f82b10
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
f82b10
---
f82b10
 include/linux/efi.h   |  6 ++++
f82b10
 init/Kconfig          |  9 ++++++
f82b10
 kernel/Makefile       |  3 ++
f82b10
 kernel/modsign_uefi.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++
f82b10
 4 files changed, 108 insertions(+)
f82b10
 create mode 100644 kernel/modsign_uefi.c
f82b10
f82b10
diff --git a/include/linux/efi.h b/include/linux/efi.h
Josh Boyer a8e5ae
index 64b3e55..76fe526 100644
f82b10
--- a/include/linux/efi.h
f82b10
+++ b/include/linux/efi.h
f82b10
@@ -394,6 +394,12 @@ typedef efi_status_t efi_query_capsule_caps_t(efi_capsule_header_t **capsules,
f82b10
 #define EFI_CERT_X509_GUID \
f82b10
     EFI_GUID(  0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 )
f82b10
 
f82b10
+#define EFI_IMAGE_SECURITY_DATABASE_GUID \
f82b10
+    EFI_GUID(  0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f )
f82b10
+
f82b10
+#define EFI_SHIM_LOCK_GUID \
f82b10
+    EFI_GUID(  0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 )
f82b10
+
f82b10
 typedef struct {
f82b10
 	efi_guid_t guid;
f82b10
 	u64 table;
f82b10
diff --git a/init/Kconfig b/init/Kconfig
Josh Boyer a8e5ae
index d972b77..27e3a82 100644
f82b10
--- a/init/Kconfig
f82b10
+++ b/init/Kconfig
f82b10
@@ -1673,6 +1673,15 @@ config MODULE_SIG_BLACKLIST
f82b10
 	  should not pass module signature verification.  If a module is
f82b10
 	  signed with something in this keyring, the load will be rejected.
f82b10
 
f82b10
+config MODULE_SIG_UEFI
f82b10
+	bool "Allow modules signed with certs stored in UEFI"
f82b10
+	depends on MODULE_SIG && MODULE_SIG_BLACKLIST && EFI
f82b10
+	select EFI_SIGNATURE_LIST_PARSER
f82b10
+	help
f82b10
+	  This will import certificates stored in UEFI and allow modules
f82b10
+	  signed with those to be loaded.  It will also disallow loading
f82b10
+	  of modules stored in the UEFI dbx variable.
f82b10
+
f82b10
 choice
f82b10
 	prompt "Which hash algorithm should modules be signed with?"
f82b10
 	depends on MODULE_SIG
f82b10
diff --git a/kernel/Makefile b/kernel/Makefile
f82b10
index 6c072b6..8848829 100644
f82b10
--- a/kernel/Makefile
f82b10
+++ b/kernel/Makefile
f82b10
@@ -55,6 +55,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
f82b10
 obj-$(CONFIG_UID16) += uid16.o
f82b10
 obj-$(CONFIG_MODULES) += module.o
f82b10
 obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o
f82b10
+obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o
f82b10
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
f82b10
 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
f82b10
 obj-$(CONFIG_KEXEC) += kexec.o
f82b10
@@ -114,6 +115,8 @@ obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
f82b10
 
f82b10
 $(obj)/configs.o: $(obj)/config_data.h
f82b10
 
f82b10
+$(obj)/modsign_uefi.o: KBUILD_CFLAGS += -fshort-wchar
f82b10
+
f82b10
 # config_data.h contains the same information as ikconfig.h but gzipped.
f82b10
 # Info from config_data can be extracted from /proc/config*
f82b10
 targets += config_data.gz
f82b10
diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c
f82b10
new file mode 100644
Josh Boyer a8e5ae
index 0000000..b9237d7
f82b10
--- /dev/null
f82b10
+++ b/kernel/modsign_uefi.c
f82b10
@@ -0,0 +1,90 @@
f82b10
+#include <linux/kernel.h>
f82b10
+#include <linux/sched.h>
f82b10
+#include <linux/cred.h>
f82b10
+#include <linux/err.h>
f82b10
+#include <linux/efi.h>
f82b10
+#include <keys/asymmetric-type.h>
f82b10
+#include "module-internal.h"
f82b10
+
f82b10
+static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size)
f82b10
+{
f82b10
+	efi_status_t status;
f82b10
+	unsigned long lsize = 4;
f82b10
+	unsigned long tmpdb[4];
f82b10
+	void *db = NULL;
f82b10
+
f82b10
+	status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
f82b10
+	if (status != EFI_BUFFER_TOO_SMALL) {
f82b10
+		pr_err("Couldn't get size: 0x%lx\n", status);
f82b10
+		return NULL;
f82b10
+	}
f82b10
+
f82b10
+	db = kmalloc(lsize, GFP_KERNEL);
f82b10
+	if (!db) {
f82b10
+		pr_err("Couldn't allocate memory for uefi cert list\n");
f82b10
+		goto out;
f82b10
+	}
f82b10
+
f82b10
+	status = efi.get_variable(name, guid, NULL, &lsize, db);
f82b10
+	if (status != EFI_SUCCESS) {
f82b10
+		kfree(db);
f82b10
+		db = NULL;
f82b10
+		pr_err("Error reading db var: 0x%lx\n", status);
f82b10
+	}
f82b10
+out:
f82b10
+	*size = lsize;
f82b10
+	return db;
f82b10
+}
f82b10
+
f82b10
+/*
f82b10
+ *  * Load the certs contained in the UEFI databases
f82b10
+ *   */
f82b10
+static int __init load_uefi_certs(void)
f82b10
+{
f82b10
+	efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
f82b10
+	efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
f82b10
+	void *db = NULL, *dbx = NULL, *mok = NULL;
f82b10
+	unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
f82b10
+	int rc = 0;
f82b10
+
f82b10
+	/* Check if SB is enabled and just return if not */
Josh Boyer a8e5ae
+	if (!efi_enabled(EFI_SECURE_BOOT))
f82b10
+		return 0;
f82b10
+
f82b10
+	/* Get db, MokListRT, and dbx.  They might not exist, so it isn't
f82b10
+	 * an error if we can't get them.
f82b10
+	 */
f82b10
+	db = get_cert_list(L"db", &secure_var, &dbsize);
f82b10
+	if (!db) {
f82b10
+		pr_err("MODSIGN: Couldn't get UEFI db list\n");
f82b10
+	} else {
f82b10
+		rc = parse_efi_signature_list(db, dbsize, modsign_keyring);
f82b10
+		if (rc)
f82b10
+			pr_err("Couldn't parse db signatures: %d\n", rc);
f82b10
+		kfree(db);
f82b10
+	}
f82b10
+
f82b10
+	mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
f82b10
+	if (!mok) {
f82b10
+		pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
f82b10
+	} else {
f82b10
+		rc = parse_efi_signature_list(mok, moksize, modsign_keyring);
f82b10
+		if (rc)
f82b10
+			pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
f82b10
+		kfree(mok);
f82b10
+	}
f82b10
+
f82b10
+	dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
f82b10
+	if (!dbx) {
f82b10
+		pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
f82b10
+	} else {
f82b10
+		rc = parse_efi_signature_list(dbx, dbxsize,
f82b10
+			modsign_blacklist);
f82b10
+		if (rc)
f82b10
+			pr_err("Couldn't parse dbx signatures: %d\n", rc);
f82b10
+		kfree(dbx);
f82b10
+	}
f82b10
+
f82b10
+	return rc;
f82b10
+}
f82b10
+late_initcall(load_uefi_certs);
f82b10
-- 
Josh Boyer b1b2d3
1.8.1.2
f82b10
f82b10
Josh Boyer b1b2d3
From 16027d676baed34a9de804dac68d48096a688b39 Mon Sep 17 00:00:00 2001
f82b10
From: Matthew Garrett <mjg@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:40:57 -0400
Josh Boyer b1b2d3
Subject: [PATCH 09/19] PCI: Lock down BAR access in secure boot environments
f82b10
f82b10
Any hardware that can potentially generate DMA has to be locked down from
f82b10
userspace in order to avoid it being possible for an attacker to cause
f82b10
arbitrary kernel behaviour. Default to paranoid - in future we can
f82b10
potentially relax this for sufficiently IOMMU-isolated devices.
f82b10
f82b10
Signed-off-by: Matthew Garrett <mjg@redhat.com>
f82b10
---
f82b10
 drivers/pci/pci-sysfs.c | 9 +++++++++
f82b10
 drivers/pci/proc.c      | 8 +++++++-
f82b10
 drivers/pci/syscall.c   | 2 +-
f82b10
 3 files changed, 17 insertions(+), 2 deletions(-)
f82b10
f82b10
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
f82b10
index 9c6e9bb..b966089 100644
f82b10
--- a/drivers/pci/pci-sysfs.c
f82b10
+++ b/drivers/pci/pci-sysfs.c
f82b10
@@ -622,6 +622,9 @@ pci_write_config(struct file* filp, struct kobject *kobj,
f82b10
 	loff_t init_off = off;
f82b10
 	u8 *data = (u8*) buf;
f82b10
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	if (off > dev->cfg_size)
f82b10
 		return 0;
f82b10
 	if (off + count > dev->cfg_size) {
f82b10
@@ -928,6 +931,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
f82b10
 	resource_size_t start, end;
f82b10
 	int i;
f82b10
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	for (i = 0; i < PCI_ROM_RESOURCE; i++)
f82b10
 		if (res == &pdev->resource[i])
f82b10
 			break;
f82b10
@@ -1035,6 +1041,9 @@ pci_write_resource_io(struct file *filp, struct kobject *kobj,
f82b10
 		      struct bin_attribute *attr, char *buf,
f82b10
 		      loff_t off, size_t count)
f82b10
 {
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	return pci_resource_io(filp, kobj, attr, buf, off, count, true);
f82b10
 }
f82b10
 
f82b10
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
f82b10
index 9b8505c..35580bc 100644
f82b10
--- a/drivers/pci/proc.c
f82b10
+++ b/drivers/pci/proc.c
f82b10
@@ -139,6 +139,9 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof
f82b10
 	int size = dp->size;
f82b10
 	int cnt;
f82b10
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	if (pos >= size)
f82b10
 		return 0;
f82b10
 	if (nbytes >= size)
f82b10
@@ -219,6 +222,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd,
f82b10
 #endif /* HAVE_PCI_MMAP */
f82b10
 	int ret = 0;
f82b10
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	switch (cmd) {
f82b10
 	case PCIIOC_CONTROLLER:
f82b10
 		ret = pci_domain_nr(dev->bus);
f82b10
@@ -259,7 +265,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma)
f82b10
 	struct pci_filp_private *fpriv = file->private_data;
f82b10
 	int i, ret;
f82b10
 
f82b10
-	if (!capable(CAP_SYS_RAWIO))
f82b10
+	if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL))
f82b10
 		return -EPERM;
f82b10
 
f82b10
 	/* Make sure the caller is mapping a real resource for this device */
f82b10
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c
f82b10
index e1c1ec5..97e785f 100644
f82b10
--- a/drivers/pci/syscall.c
f82b10
+++ b/drivers/pci/syscall.c
f82b10
@@ -92,7 +92,7 @@ SYSCALL_DEFINE5(pciconfig_write, unsigned long, bus, unsigned long, dfn,
f82b10
 	u32 dword;
f82b10
 	int err = 0;
f82b10
 
f82b10
-	if (!capable(CAP_SYS_ADMIN))
f82b10
+	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_COMPROMISE_KERNEL))
f82b10
 		return -EPERM;
f82b10
 
f82b10
 	dev = pci_get_bus_and_slot(bus, dfn);
f82b10
-- 
Josh Boyer b1b2d3
1.8.1.2
f82b10
f82b10
Josh Boyer b1b2d3
From 9ff1537bbe8c22bbf7f992027da43d4fe8da0860 Mon Sep 17 00:00:00 2001
f82b10
From: Matthew Garrett <mjg@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:40:58 -0400
Josh Boyer b1b2d3
Subject: [PATCH 10/19] x86: Lock down IO port access in secure boot
f82b10
 environments
f82b10
f82b10
IO port access would permit users to gain access to PCI configuration
f82b10
registers, which in turn (on a lot of hardware) give access to MMIO register
f82b10
space. This would potentially permit root to trigger arbitrary DMA, so lock
f82b10
it down by default.
f82b10
f82b10
Signed-off-by: Matthew Garrett <mjg@redhat.com>
f82b10
---
f82b10
 arch/x86/kernel/ioport.c | 4 ++--
f82b10
 drivers/char/mem.c       | 3 +++
f82b10
 2 files changed, 5 insertions(+), 2 deletions(-)
f82b10
f82b10
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
f82b10
index 8c96897..a2578c4 100644
f82b10
--- a/arch/x86/kernel/ioport.c
f82b10
+++ b/arch/x86/kernel/ioport.c
f82b10
@@ -28,7 +28,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
f82b10
 
f82b10
 	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
f82b10
 		return -EINVAL;
f82b10
-	if (turn_on && !capable(CAP_SYS_RAWIO))
f82b10
+	if (turn_on && (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL)))
f82b10
 		return -EPERM;
f82b10
 
f82b10
 	/*
f82b10
@@ -102,7 +102,7 @@ long sys_iopl(unsigned int level, struct pt_regs *regs)
f82b10
 		return -EINVAL;
f82b10
 	/* Trying to gain more privileges? */
f82b10
 	if (level > old) {
f82b10
-		if (!capable(CAP_SYS_RAWIO))
f82b10
+		if (!capable(CAP_SYS_RAWIO) || !capable(CAP_COMPROMISE_KERNEL))
f82b10
 			return -EPERM;
f82b10
 	}
f82b10
 	regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
f82b10
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
f82b10
index c6fa3bc..fc28099 100644
f82b10
--- a/drivers/char/mem.c
f82b10
+++ b/drivers/char/mem.c
f82b10
@@ -597,6 +597,9 @@ static ssize_t write_port(struct file *file, const char __user *buf,
f82b10
 	unsigned long i = *ppos;
f82b10
 	const char __user * tmp = buf;
f82b10
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	if (!access_ok(VERIFY_READ, buf, count))
f82b10
 		return -EFAULT;
f82b10
 	while (count-- > 0 && i < 65536) {
Josh Boyer 5e72ee
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 4fc17c
Josh Boyer 5e72ee
Josh Boyer b1b2d3
From 3b27408b1ced1ec83a3ce27f9d51161dbf7cea9a Mon Sep 17 00:00:00 2001
f82b10
From: Matthew Garrett <mjg@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:40:59 -0400
Josh Boyer b1b2d3
Subject: [PATCH 11/19] ACPI: Limit access to custom_method
Josh Boyer 5e72ee
f82b10
It must be impossible for even root to get code executed in kernel context
f82b10
under a secure boot environment. custom_method effectively allows arbitrary
f82b10
access to system memory, so it needs to have a capability check here.
Josh Boyer 5e72ee
f82b10
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 5e72ee
---
f82b10
 drivers/acpi/custom_method.c | 3 +++
f82b10
 1 file changed, 3 insertions(+)
Josh Boyer 5e72ee
f82b10
diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
f82b10
index 5d42c24..247d58b 100644
f82b10
--- a/drivers/acpi/custom_method.c
f82b10
+++ b/drivers/acpi/custom_method.c
f82b10
@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
f82b10
 	struct acpi_table_header table;
f82b10
 	acpi_status status;
Josh Boyer 5e72ee
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
Josh Boyer 5e72ee
+
f82b10
 	if (!(*ppos)) {
f82b10
 		/* parse the table header to get the table length */
f82b10
 		if (count <= sizeof(struct acpi_table_header))
Josh Boyer 5e72ee
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 4fc17c
Josh Boyer 5e72ee
Josh Boyer b1b2d3
From fb618a04089d454b7ade68c00a2b9c7dbac013f9 Mon Sep 17 00:00:00 2001
f82b10
From: Matthew Garrett <mjg@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:41:00 -0400
Josh Boyer b1b2d3
Subject: [PATCH 12/19] asus-wmi: Restrict debugfs interface
Josh Boyer 5e72ee
f82b10
We have no way of validating what all of the Asus WMI methods do on a
f82b10
given machine, and there's a risk that some will allow hardware state to
f82b10
be manipulated in such a way that arbitrary code can be executed in the
f82b10
kernel. Add a capability check to prevent that.
Josh Boyer 5e72ee
f82b10
Signed-off-by: Matthew Garrett <mjg@redhat.com>
Josh Boyer 5e72ee
---
f82b10
 drivers/platform/x86/asus-wmi.c | 9 +++++++++
f82b10
 1 file changed, 9 insertions(+)
Josh Boyer 5e72ee
f82b10
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
f82b10
index f80ae4d..059195f 100644
f82b10
--- a/drivers/platform/x86/asus-wmi.c
f82b10
+++ b/drivers/platform/x86/asus-wmi.c
f82b10
@@ -1521,6 +1521,9 @@ static int show_dsts(struct seq_file *m, void *data)
f82b10
 	int err;
f82b10
 	u32 retval = -1;
Josh Boyer 5e72ee
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
Josh Boyer 5e72ee
+
f82b10
 	err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
Josh Boyer 5e72ee
 
f82b10
 	if (err < 0)
f82b10
@@ -1537,6 +1540,9 @@ static int show_devs(struct seq_file *m, void *data)
f82b10
 	int err;
f82b10
 	u32 retval = -1;
Josh Boyer 5e72ee
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
Josh Boyer 5e72ee
+
f82b10
 	err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
f82b10
 				    &retval);
f82b10
 
f82b10
@@ -1561,6 +1567,9 @@ static int show_call(struct seq_file *m, void *data)
f82b10
 	union acpi_object *obj;
f82b10
 	acpi_status status;
f82b10
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
Josh Boyer 5e72ee
+
f82b10
 	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
f82b10
 				     1, asus->debug.method_id,
f82b10
 				     &input, &output);
f82b10
-- 
Josh Boyer b1b2d3
1.8.1.2
f82b10
f82b10
Josh Boyer b1b2d3
From e515bbd5410d00835390fd8981aa9029e7b22b73 Mon Sep 17 00:00:00 2001
f82b10
From: Matthew Garrett <mjg@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:41:01 -0400
Josh Boyer b1b2d3
Subject: [PATCH 13/19] Restrict /dev/mem and /dev/kmem in secure boot setups
f82b10
f82b10
Allowing users to write to address space makes it possible for the kernel
f82b10
to be subverted. Restrict this when we need to protect the kernel.
f82b10
f82b10
Signed-off-by: Matthew Garrett <mjg@redhat.com>
f82b10
---
f82b10
 drivers/char/mem.c | 6 ++++++
f82b10
 1 file changed, 6 insertions(+)
f82b10
f82b10
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
f82b10
index fc28099..b5df7a8 100644
f82b10
--- a/drivers/char/mem.c
f82b10
+++ b/drivers/char/mem.c
f82b10
@@ -158,6 +158,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
f82b10
 	unsigned long copied;
f82b10
 	void *ptr;
Josh Boyer 5e72ee
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	if (!valid_phys_addr_range(p, count))
f82b10
 		return -EFAULT;
Josh Boyer 5e72ee
 
f82b10
@@ -530,6 +533,9 @@ static ssize_t write_kmem(struct file *file, const char __user *buf,
f82b10
 	char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
f82b10
 	int err = 0;
Josh Boyer 5e72ee
 
f82b10
+	if (!capable(CAP_COMPROMISE_KERNEL))
f82b10
+		return -EPERM;
f82b10
+
f82b10
 	if (p < (unsigned long) high_memory) {
f82b10
 		unsigned long to_write = min_t(unsigned long, count,
f82b10
 					       (unsigned long)high_memory - p);
f82b10
-- 
Josh Boyer b1b2d3
1.8.1.2
f82b10
f82b10
Josh Boyer b1b2d3
From fe27dd192ef250abcbaba973a14d43b21d7be497 Mon Sep 17 00:00:00 2001
f82b10
From: Josh Boyer <jwboyer@redhat.com>
f82b10
Date: Thu, 20 Sep 2012 10:41:04 -0400
Josh Boyer b1b2d3
Subject: [PATCH 14/19] acpi: Ignore acpi_rsdp kernel parameter in a secure
f82b10
 boot environment
f82b10
f82b10
This option allows userspace to pass the RSDP address to the kernel.  This
f82b10
could potentially be used to circumvent the secure boot trust model.
f82b10
We ignore the setting if we don't have the CAP_COMPROMISE_KERNEL capability.
f82b10
f82b10
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
f82b10
---
f82b10
 drivers/acpi/osl.c | 2 +-
f82b10
 1 file changed, 1 insertion(+), 1 deletion(-)
f82b10
f82b10
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
Josh Boyer a8e5ae
index bd22f86..88251d2 100644
f82b10
--- a/drivers/acpi/osl.c
f82b10
+++ b/drivers/acpi/osl.c
f82b10
@@ -246,7 +246,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp);
f82b10
 acpi_physical_address __init acpi_os_get_root_pointer(void)
Josh Boyer 5e72ee
 {
f82b10
 #ifdef CONFIG_KEXEC
f82b10
-	if (acpi_rsdp)
f82b10
+	if (acpi_rsdp && capable(CAP_COMPROMISE_KERNEL))
f82b10
 		return acpi_rsdp;
f82b10
 #endif
Josh Boyer 5e72ee
 
f82b10
-- 
Josh Boyer b1b2d3
1.8.1.2
f82b10
f82b10
Josh Boyer b1b2d3
From c937b2c8e179bfdadb6617c0028f558e4d701e46 Mon Sep 17 00:00:00 2001
f82b10
From: Matthew Garrett <mjg@redhat.com>
f82b10
Date: Tue, 4 Sep 2012 11:55:13 -0400
Josh Boyer b1b2d3
Subject: [PATCH 15/19] kexec: Disable in a secure boot environment
f82b10
f82b10
kexec could be used as a vector for a malicious user to use a signed kernel
f82b10
to circumvent the secure boot trust model. In the long run we'll want to
f82b10
support signed kexec payloads, but for the moment we should just disable
f82b10
loading entirely in that situation.
f82b10
f82b10
Signed-off-by: Matthew Garrett <mjg@redhat.com>
f82b10
---
f82b10
 kernel/kexec.c | 2 +-
f82b10
 1 file changed, 1 insertion(+), 1 deletion(-)
f82b10
f82b10
diff --git a/kernel/kexec.c b/kernel/kexec.c
f82b10
index 5e4bd78..dd464e0 100644
f82b10
--- a/kernel/kexec.c
f82b10
+++ b/kernel/kexec.c
f82b10
@@ -943,7 +943,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
f82b10
 	int result;
Josh Boyer 5e72ee
 
f82b10
 	/* We only trust the superuser with rebooting the system. */
f82b10
-	if (!capable(CAP_SYS_BOOT))
f82b10
+	if (!capable(CAP_SYS_BOOT) || !capable(CAP_COMPROMISE_KERNEL))
f82b10
 		return -EPERM;
Josh Boyer 5e72ee
 
f82b10
 	/*
Josh Boyer 5e72ee
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 5e72ee
Josh Boyer 5e72ee
Josh Boyer b1b2d3
From f08e390045266d53543a55afa16ca4be5a1c6316 Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee
From: Josh Boyer <jwboyer@redhat.com>
f82b10
Date: Fri, 5 Oct 2012 10:12:48 -0400
Josh Boyer b1b2d3
Subject: [PATCH 16/19] MODSIGN: Always enforce module signing in a Secure Boot
f82b10
 environment
Josh Boyer 5e72ee
f82b10
If a machine is booted into a Secure Boot environment, we need to
f82b10
protect the trust model.  This requires that all modules be signed
f82b10
with a key that is in the kernel's _modsign keyring.  The checks for
f82b10
this are already done via the 'sig_enforce' module parameter.  Make
f82b10
this visible within the kernel and force it to be true.
Josh Boyer 5e72ee
Josh Boyer 5e72ee
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee
---
f82b10
 kernel/cred.c   | 8 ++++++++
f82b10
 kernel/module.c | 4 ++--
f82b10
 2 files changed, 10 insertions(+), 2 deletions(-)
Josh Boyer 5e72ee
f82b10
diff --git a/kernel/cred.c b/kernel/cred.c
f82b10
index c3f4e3e..c5554e0 100644
f82b10
--- a/kernel/cred.c
f82b10
+++ b/kernel/cred.c
f82b10
@@ -565,11 +565,19 @@ void __init cred_init(void)
f82b10
 				     0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
f82b10
 }
Josh Boyer 5e72ee
 
f82b10
+#ifdef CONFIG_MODULE_SIG
f82b10
+extern bool sig_enforce;
f82b10
+#endif
Josh Boyer 4fc17c
+
f82b10
 void __init secureboot_enable()
f82b10
 {
f82b10
 	pr_info("Secure boot enabled\n");
f82b10
 	cap_lower((&init_cred)->cap_bset, CAP_COMPROMISE_KERNEL);
f82b10
 	cap_lower((&init_cred)->cap_permitted, CAP_COMPROMISE_KERNEL);
f82b10
+#ifdef CONFIG_MODULE_SIG
f82b10
+	/* Enable module signature enforcing */
f82b10
+	sig_enforce = true;
f82b10
+#endif
f82b10
 }
Josh Boyer 5e72ee
 
f82b10
 /* Dummy Secure Boot enable option to fake out UEFI SB=1 */
f82b10
diff --git a/kernel/module.c b/kernel/module.c
Josh Boyer a8e5ae
index eab0827..93a16dc 100644
f82b10
--- a/kernel/module.c
f82b10
+++ b/kernel/module.c
f82b10
@@ -109,9 +109,9 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
Josh Boyer 5e72ee
 
f82b10
 #ifdef CONFIG_MODULE_SIG
f82b10
 #ifdef CONFIG_MODULE_SIG_FORCE
f82b10
-static bool sig_enforce = true;
f82b10
+bool sig_enforce = true;
f82b10
 #else
f82b10
-static bool sig_enforce = false;
f82b10
+bool sig_enforce = false;
Josh Boyer 5e72ee
 
f82b10
 static int param_set_bool_enable_only(const char *val,
f82b10
 				      const struct kernel_param *kp)
Josh Boyer 5e72ee
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 5e72ee
Josh Boyer b07f54
Josh Boyer b1b2d3
From 54ba1eec5847d964b1d458a240b50271b9a356a4 Mon Sep 17 00:00:00 2001
Josh Boyer 5e72ee
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee
Date: Fri, 26 Oct 2012 14:02:09 -0400
Josh Boyer b1b2d3
Subject: [PATCH 17/19] hibernate: Disable in a Secure Boot environment
Josh Boyer 5e72ee
Josh Boyer 5e72ee
There is currently no way to verify the resume image when returning
Josh Boyer 5e72ee
from hibernate.  This might compromise the secure boot trust model,
Josh Boyer 5e72ee
so until we can work with signed hibernate images we disable it in
Josh Boyer 5e72ee
a Secure Boot environment.
Josh Boyer 5e72ee
Josh Boyer 5e72ee
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer 5e72ee
---
Josh Boyer de4763
 kernel/power/hibernate.c | 15 ++++++++++++++-
Josh Boyer de4763
 kernel/power/main.c      |  7 ++++++-
Josh Boyer b07f54
 kernel/power/user.c      |  3 +++
Josh Boyer de4763
 3 files changed, 23 insertions(+), 2 deletions(-)
Josh Boyer 5e72ee
Josh Boyer 5e72ee
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
Josh Boyer a8e5ae
index b26f5f1..7f63cb4 100644
Josh Boyer 5e72ee
--- a/kernel/power/hibernate.c
Josh Boyer 5e72ee
+++ b/kernel/power/hibernate.c
Josh Boyer de4763
@@ -28,6 +28,7 @@
Josh Boyer de4763
 #include <linux/syscore_ops.h>
Josh Boyer de4763
 #include <linux/ctype.h>
Josh Boyer de4763
 #include <linux/genhd.h>
Josh Boyer de4763
+#include <linux/efi.h>
Josh Boyer de4763
 
Josh Boyer de4763
 #include "power.h"
Josh Boyer de4763
 
Josh Boyer de4763
@@ -632,6 +633,10 @@ int hibernate(void)
Josh Boyer 5e72ee
 {
Josh Boyer 5e72ee
 	int error;
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
+	if (!capable(CAP_COMPROMISE_KERNEL)) {
Josh Boyer 5e72ee
+		return -EPERM;
Josh Boyer 5e72ee
+	}
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
 	lock_system_sleep();
Josh Boyer 5e72ee
 	/* The snapshot device should not be opened while we're running */
Josh Boyer 5e72ee
 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
Josh Boyer de4763
@@ -723,7 +728,7 @@ static int software_resume(void)
Josh Boyer 5e72ee
 	/*
Josh Boyer 5e72ee
 	 * If the user said "noresume".. bail out early.
Josh Boyer 5e72ee
 	 */
Josh Boyer 5e72ee
-	if (noresume)
Josh Boyer 5e72ee
+	if (noresume || !capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 5e72ee
 		return 0;
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
 	/*
Josh Boyer de4763
@@ -889,6 +894,11 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr,
Josh Boyer 5e72ee
 	int i;
Josh Boyer 5e72ee
 	char *start = buf;
Josh Boyer 5e72ee
 
Josh Boyer a8e5ae
+	if (efi_enabled(EFI_SECURE_BOOT)) {
Josh Boyer 5e72ee
+		buf += sprintf(buf, "[%s]\n", "disabled");
Josh Boyer 5e72ee
+		return buf-start;
Josh Boyer 5e72ee
+	}
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
 	for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
Josh Boyer 5e72ee
 		if (!hibernation_modes[i])
Josh Boyer 5e72ee
 			continue;
Josh Boyer de4763
@@ -923,6 +933,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr,
Josh Boyer 5e72ee
 	char *p;
Josh Boyer 5e72ee
 	int mode = HIBERNATION_INVALID;
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 5e72ee
+		return -EPERM;
Josh Boyer 5e72ee
+
Josh Boyer 5e72ee
 	p = memchr(buf, '\n', n);
Josh Boyer 5e72ee
 	len = p ? p - buf : n;
Josh Boyer 5e72ee
 
Josh Boyer 5e72ee
diff --git a/kernel/power/main.c b/kernel/power/main.c
Josh Boyer a8e5ae
index 1c16f91..4f915fc 100644
Josh Boyer 5e72ee
--- a/kernel/power/main.c
Josh Boyer 5e72ee
+++ b/kernel/power/main.c
Josh Boyer de4763
@@ -15,6 +15,7 @@
Josh Boyer de4763
 #include <linux/workqueue.h>
Josh Boyer de4763
 #include <linux/debugfs.h>
Josh Boyer de4763
 #include <linux/seq_file.h>
Josh Boyer de4763
+#include <linux/efi.h>
Josh Boyer de4763
 
Josh Boyer de4763
 #include "power.h"
Josh Boyer de4763
 
Josh Boyer de4763
@@ -301,7 +302,11 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
Josh Boyer 5e72ee
 	}
Josh Boyer 5e72ee
 #endif
Josh Boyer 5e72ee
 #ifdef CONFIG_HIBERNATION
Josh Boyer 5e72ee
-	s += sprintf(s, "%s\n", "disk");
Josh Boyer a8e5ae
+	if (!efi_enabled(EFI_SECURE_BOOT)) {
Josh Boyer 5e72ee
+		s += sprintf(s, "%s\n", "disk");
Josh Boyer de4763
+	} else {
Josh Boyer de4763
+		s += sprintf(s, "\n");
Josh Boyer 5e72ee
+	}
Josh Boyer 5e72ee
 #else
Josh Boyer 5e72ee
 	if (s != buf)
Josh Boyer 5e72ee
 		/* convert the last space to a newline */
Josh Boyer b07f54
diff --git a/kernel/power/user.c b/kernel/power/user.c
Josh Boyer b07f54
index 4ed81e7..b11a0f4 100644
Josh Boyer b07f54
--- a/kernel/power/user.c
Josh Boyer b07f54
+++ b/kernel/power/user.c
Josh Boyer b07f54
@@ -48,6 +48,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
Josh Boyer b07f54
 	struct snapshot_data *data;
Josh Boyer b07f54
 	int error;
Josh Boyer b07f54
 
Josh Boyer b07f54
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer b07f54
+		return -EPERM;
Josh Boyer b07f54
+
Josh Boyer b07f54
 	lock_system_sleep();
Josh Boyer b07f54
 
Josh Boyer b07f54
 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
Josh Boyer 5e72ee
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer b1b2d3
Josh Boyer 5e72ee
Josh Boyer b1b2d3
From 686090054f6c3784218b318c7adcc3c1f0ca5069 Mon Sep 17 00:00:00 2001
Josh Boyer b34201
From: Josh Boyer <jwboyer@redhat.com>
Josh Boyer b34201
Date: Tue, 5 Feb 2013 19:25:05 -0500
Josh Boyer b1b2d3
Subject: [PATCH 18/19] efi: Disable secure boot if shim is in insecure mode
Josh Boyer b34201
Josh Boyer b34201
A user can manually tell the shim boot loader to disable validation of
Josh Boyer b34201
images it loads.  When a user does this, it creates a UEFI variable called
Josh Boyer b34201
MokSBState that does not have the runtime attribute set.  Given that the
Josh Boyer b34201
user explicitly disabled validation, we can honor that and not enable
Josh Boyer b34201
secure boot mode if that variable is set.
Josh Boyer b34201
Josh Boyer b34201
Signed-off-by: Josh Boyer <jwboyer@redhat.com>
Josh Boyer b34201
---
Josh Boyer b34201
 arch/x86/boot/compressed/eboot.c | 20 +++++++++++++++++++-
Josh Boyer b34201
 1 file changed, 19 insertions(+), 1 deletion(-)
Josh Boyer b34201
Josh Boyer b34201
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
Josh Boyer b34201
index 96bd86b..6e1331c 100644
Josh Boyer b34201
--- a/arch/x86/boot/compressed/eboot.c
Josh Boyer b34201
+++ b/arch/x86/boot/compressed/eboot.c
Josh Boyer b34201
@@ -851,8 +851,9 @@ fail:
Josh Boyer b34201
 
Josh Boyer b34201
 static int get_secure_boot(efi_system_table_t *_table)
Josh Boyer b34201
 {
Josh Boyer b34201
-	u8 sb, setup;
Josh Boyer b34201
+	u8 sb, setup, moksbstate;
Josh Boyer b34201
 	unsigned long datasize = sizeof(sb);
Josh Boyer b34201
+	u32 attr;
Josh Boyer b34201
 	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
Josh Boyer b34201
 	efi_status_t status;
Josh Boyer b34201
 
Josh Boyer b34201
@@ -876,6 +877,23 @@ static int get_secure_boot(efi_system_table_t *_table)
Josh Boyer b34201
 	if (setup == 1)
Josh Boyer b34201
 		return 0;
Josh Boyer b34201
 
Josh Boyer b34201
+	/* See if a user has put shim into insecure_mode.  If so, and the variable
Josh Boyer b34201
+	 * doesn't have the runtime attribute set, we might as well honor that.
Josh Boyer b34201
+	 */
Josh Boyer b34201
+	var_guid = EFI_SHIM_LOCK_GUID;
Josh Boyer b34201
+	status = efi_call_phys5(sys_table->runtime->get_variable,
Josh Boyer b34201
+				L"MokSBState", &var_guid, &attr, &datasize,
Josh Boyer b34201
+				&moksbstate);
Josh Boyer b34201
+
Josh Boyer b34201
+	/* If it fails, we don't care why.  Default to secure */
Josh Boyer b34201
+	if (status != EFI_SUCCESS)
Josh Boyer b34201
+		return 1;
Josh Boyer b34201
+
Josh Boyer b34201
+	if (!(attr & EFI_VARIABLE_RUNTIME_ACCESS)) {
Josh Boyer b34201
+		if (moksbstate == 1)
Josh Boyer b34201
+			return 0;
Josh Boyer b34201
+	}
Josh Boyer b34201
+
Josh Boyer b34201
 	return 1;
Josh Boyer b34201
 }
Josh Boyer b34201
 
Josh Boyer b34201
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer b1b2d3
Josh Boyer b1b2d3
Josh Boyer b1b2d3
From df607d2d5061b04f8a686cd74edd72c1f2836d8c Mon Sep 17 00:00:00 2001
Josh Boyer b1b2d3
From: Kees Cook <keescook@chromium.org>
Josh Boyer b1b2d3
Date: Fri, 8 Feb 2013 11:12:13 -0800
Josh Boyer b1b2d3
Subject: [PATCH 19/19] x86: Lock down MSR writing in secure boot
Josh Boyer 79353e
Josh Boyer 79353e
Writing to MSRs should not be allowed unless CAP_COMPROMISE_KERNEL is
Josh Boyer 79353e
set since it could lead to execution of arbitrary code in kernel mode.
Josh Boyer 79353e
Josh Boyer 79353e
Signed-off-by: Kees Cook <keescook@chromium.org>
Josh Boyer 79353e
---
Josh Boyer b1b2d3
 arch/x86/kernel/msr.c | 7 +++++++
Josh Boyer 79353e
 1 file changed, 7 insertions(+)
Josh Boyer 79353e
Josh Boyer 79353e
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
Josh Boyer 79353e
index 4929502..adaab3d 100644
Josh Boyer 79353e
--- a/arch/x86/kernel/msr.c
Josh Boyer 79353e
+++ b/arch/x86/kernel/msr.c
Josh Boyer 79353e
@@ -103,6 +103,9 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
Josh Boyer 79353e
 	int err = 0;
Josh Boyer 79353e
 	ssize_t bytes = 0;
Josh Boyer 79353e
 
Josh Boyer 79353e
+	if (!capable(CAP_COMPROMISE_KERNEL))
Josh Boyer 79353e
+		return -EPERM;
Josh Boyer 79353e
+
Josh Boyer 79353e
 	if (count % 8)
Josh Boyer 79353e
 		return -EINVAL;	/* Invalid chunk size */
Josh Boyer 79353e
 
Josh Boyer 79353e
@@ -150,6 +153,10 @@ static long msr_ioctl(struct file *file, unsigned int ioc, unsigned long arg)
Josh Boyer 79353e
 			err = -EBADF;
Josh Boyer 79353e
 			break;
Josh Boyer 79353e
 		}
Josh Boyer 79353e
+		if (!capable(CAP_COMPROMISE_KERNEL)) {
Josh Boyer 79353e
+			err = -EPERM;
Josh Boyer 79353e
+			break;
Josh Boyer 79353e
+		}
Josh Boyer 79353e
 		if (copy_from_user(&regs, uregs, sizeof regs)) {
Josh Boyer 79353e
 			err = -EFAULT;
Josh Boyer 79353e
 			break;
Josh Boyer 79353e
-- 
Josh Boyer b1b2d3
1.8.1.2
Josh Boyer 79353e