[kernel] Add system_keyring patches back in

Josh Boyer jwboyer at fedoraproject.org
Tue Sep 3 21:30:22 UTC 2013


commit d7ee6f3b0e2cb9569f384eeac7d1c8f5c6a93e91
Author: Josh Boyer <jwboyer at redhat.com>
Date:   Tue Sep 3 17:26:36 2013 -0400

    Add system_keyring patches back in

 config-x86-generic     |    3 +-
 kernel.spec            |    7 +-
 keys-x509-improv.patch | 1580 ++++++++++++++++++++++++++++++++++++++++++++++++
 modsign-uefi.patch     |  200 ++++---
 sb-hibernate.patch     |   23 +-
 secure-modules.patch   |  284 +++++----
 6 files changed, 1852 insertions(+), 245 deletions(-)
---
diff --git a/config-x86-generic b/config-x86-generic
index 33fd369..3c3a0dd 100644
--- a/config-x86-generic
+++ b/config-x86-generic
@@ -441,12 +441,13 @@ CONFIG_VMWARE_VMCI_VSOCKETS=m
 CONFIG_XZ_DEC_X86=y
 
 CONFIG_MPILIB=y
+CONFIG_SYSTEM_TRUSTED_KEYRING=y
+CONFIG_SYSTEM_BLACKLIST_KEYRING=y
 CONFIG_MODULE_SIG=y
 CONFIG_MODULE_SIG_ALL=y
 # CONFIG_MODULE_SIG_SHA1 is not set
 CONFIG_MODULE_SIG_SHA256=y
 # CONFIG_MODULE_SIG_FORCE is not set
-CONFIG_MODULE_SIG_BLACKLIST=y
 CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE=y
 CONFIG_EFI_SIGNATURE_LIST_PARSER=y
 
diff --git a/kernel.spec b/kernel.spec
index 31ee5da..5e85bac 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -62,7 +62,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be appended after the rcX and
 # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
 #
-%global baserelease 1
+%global baserelease 3
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -651,6 +651,7 @@ Patch800: crash-driver.patch
 # keys
 Patch900: keys-expand-keyring.patch
 Patch901: keys-krb-support.patch
+Patch902: keys-x509-improv.patch
 
 # secure boot
 Patch1000: secure-modules.patch
@@ -1394,6 +1395,7 @@ ApplyPatch crash-driver.patch
 # keys
 ApplyPatch keys-expand-keyring.patch
 ApplyPatch keys-krb-support.patch
+ApplyPatch keys-x509-improv.patch
 
 # secure boot
 ApplyPatch secure-modules.patch
@@ -2280,6 +2282,9 @@ fi
 #                                    ||----w |
 #                                    ||     ||
 %changelog
+* Tue Sep 03 2013 Josh Boyer <jwboyer at fedoraproject.org> - 3.11.0-3
+- Add system_keyring patches back in
+
 * Tue Sep 03 2013 Kyle McMartin <kyle at redhat.com>
 - Pull in some Calxeda highbank fixes that are destined for 3.12
 - Add a %with_extra twiddle to disable building kernel-modules-extra
diff --git a/keys-x509-improv.patch b/keys-x509-improv.patch
new file mode 100644
index 0000000..b3341cf
--- /dev/null
+++ b/keys-x509-improv.patch
@@ -0,0 +1,1580 @@
+From abaac4978b6719e7ae12babb6be5e35184b61cde Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:07:13 +0100
+Subject: [PATCH 01/14] KEYS: Load *.x509 files into kernel keyring
+
+Load all the files matching the pattern "*.x509" that are to be found in kernel
+base source dir and base build dir into the module signing keyring.
+
+The "extra_certificates" file is then redundant.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+---
+ kernel/Makefile              | 35 +++++++++++++++++++++++++++++------
+ kernel/modsign_certificate.S |  3 +--
+ 2 files changed, 30 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/Makefile b/kernel/Makefile
+index 470839d..4a2ee4e 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -141,17 +141,40 @@ $(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
+ 	$(call if_changed,bc)
+ 
+ ifeq ($(CONFIG_MODULE_SIG),y)
++###############################################################################
+ #
+-# Pull the signing certificate and any extra certificates into the kernel
++# Roll all the X.509 certificates that we can find together and pull
++# them into the kernel.
+ #
++###############################################################################
++X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509)
++X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += signing_key.x509
++X509_CERTIFICATES := $(sort $(X509_CERTIFICATES-y))
++
++ifeq ($(X509_CERTIFICATES),)
++$(warning *** No X.509 certificates found ***)
++endif
++
++ifneq ($(wildcard $(obj)/.x509.list),)
++ifneq ($(shell cat $(obj)/.x509.list),$(X509_CERTIFICATES))
++$(info X.509 certificate list changed)
++$(shell rm $(obj)/.x509.list)
++endif
++endif
++
++kernel/modsign_certificate.o: $(obj)/x509_certificate_list
+ 
+-quiet_cmd_touch = TOUCH   $@
+-      cmd_touch = touch   $@
++quiet_cmd_x509certs  = CERTS   $@
++      cmd_x509certs  = cat $(X509_CERTIFICATES) /dev/null >$@
++targets += $(obj)/x509_certificate_list
++$(obj)/x509_certificate_list: $(X509_CERTIFICATES) $(obj)/.x509.list
++	$(call if_changed,x509certs)
+ 
+-extra_certificates:
+-	$(call cmd,touch)
++targets += $(obj)/.x509.list
++$(obj)/.x509.list:
++	@echo $(X509_CERTIFICATES) >$@
+ 
+-kernel/modsign_certificate.o: signing_key.x509 extra_certificates
++clean-files := x509_certificate_list .x509.list
+ 
+ ###############################################################################
+ #
+diff --git a/kernel/modsign_certificate.S b/kernel/modsign_certificate.S
+index 4a9a86d..6fe03c7 100644
+--- a/kernel/modsign_certificate.S
++++ b/kernel/modsign_certificate.S
+@@ -7,6 +7,5 @@
+ 	.section ".init.data","aw"
+ 
+ GLOBAL(modsign_certificate_list)
+-	.incbin "signing_key.x509"
+-	.incbin "extra_certificates"
++	.incbin "kernel/x509_certificate_list"
+ GLOBAL(modsign_certificate_list_end)
+-- 
+1.8.3.1
+
+
+
+From 2d6ac2896c3b4b48be96b7dbdfda1668609e35aa Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:07:30 +0100
+Subject: [PATCH 03/14] KEYS: Separate the kernel signature checking keyring
+ from module signing
+
+Separate the kernel signature checking keyring from module signing so that it
+can be used by code other than the module-signing code.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+---
+ include/keys/system_keyring.h |  23 ++++++++++
+ init/Kconfig                  |  13 ++++++
+ kernel/Makefile               |  17 ++++---
+ kernel/modsign_certificate.S  |  11 -----
+ kernel/modsign_pubkey.c       | 104 ------------------------------------------
+ kernel/module-internal.h      |   2 -
+ kernel/module_signing.c       |   3 +-
+ kernel/system_certificates.S  |  11 +++++
+ kernel/system_keyring.c       | 103 +++++++++++++++++++++++++++++++++++++++++
+ 9 files changed, 163 insertions(+), 124 deletions(-)
+ create mode 100644 include/keys/system_keyring.h
+ delete mode 100644 kernel/modsign_certificate.S
+ delete mode 100644 kernel/modsign_pubkey.c
+ create mode 100644 kernel/system_certificates.S
+ create mode 100644 kernel/system_keyring.c
+
+diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
+new file mode 100644
+index 0000000..8dabc39
+--- /dev/null
++++ b/include/keys/system_keyring.h
+@@ -0,0 +1,23 @@
++/* System keyring containing trusted public keys.
++ *
++ * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells at redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++#ifndef _KEYS_SYSTEM_KEYRING_H
++#define _KEYS_SYSTEM_KEYRING_H
++
++#ifdef CONFIG_SYSTEM_TRUSTED_KEYRING
++
++#include <linux/key.h>
++
++extern struct key *system_trusted_keyring;
++
++#endif
++
++#endif /* _KEYS_SYSTEM_KEYRING_H */
+diff --git a/init/Kconfig b/init/Kconfig
+index 247084b..6abf0e0 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1664,6 +1664,18 @@ config BASE_SMALL
+ 	default 0 if BASE_FULL
+ 	default 1 if !BASE_FULL
+ 
++config SYSTEM_TRUSTED_KEYRING
++	bool "Provide system-wide ring of trusted keys"
++	depends on KEYS
++	help
++	  Provide a system keyring to which trusted keys can be added.  Keys in
++	  the keyring are considered to be trusted.  Keys may be added at will
++	  by the kernel from compiled-in data and from hardware key stores, but
++	  userspace may only add extra keys if those keys can be verified by
++	  keys already in the keyring.
++
++	  Keys in this keyring are used by module signature checking.
++
+ menuconfig MODULES
+ 	bool "Enable loadable module support"
+ 	help
+@@ -1736,6 +1748,7 @@ config MODULE_SRCVERSION_ALL
+ config MODULE_SIG
+ 	bool "Module signature verification"
+ 	depends on MODULES
++	select SYSTEM_TRUSTED_KEYRING
+ 	select KEYS
+ 	select CRYPTO
+ 	select ASYMMETRIC_KEY_TYPE
+diff --git a/kernel/Makefile b/kernel/Makefile
+index 7bd1565..68f7182 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -52,8 +52,9 @@ obj-$(CONFIG_SMP) += spinlock.o
+ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
+ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
+ obj-$(CONFIG_UID16) += uid16.o
++obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
+ obj-$(CONFIG_MODULES) += module.o
+-obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o
++obj-$(CONFIG_MODULE_SIG) += module_signing.o
+ obj-$(CONFIG_KALLSYMS) += kallsyms.o
+ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
+ obj-$(CONFIG_KEXEC) += kexec.o
+@@ -140,13 +141,14 @@ targets += timeconst.h
+ $(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
+ 	$(call if_changed,bc)
+ 
+-ifeq ($(CONFIG_MODULE_SIG),y)
+ ###############################################################################
+ #
+-# Roll all the X.509 certificates that we can find together and pull
+-# them into the kernel.
++# Roll all the X.509 certificates that we can find together and pull them into
++# the kernel so that they get loaded into the system trusted keyring during
++# boot.
+ #
+ ###############################################################################
++ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
+ X509_CERTIFICATES-y := $(wildcard *.x509) $(wildcard $(srctree)/*.x509)
+ X509_CERTIFICATES-$(CONFIG_MODULE_SIG) += signing_key.x509
+ X509_CERTIFICATES := $(sort $(realpath $(X509_CERTIFICATES-y)))
+@@ -162,10 +164,11 @@ $(shell rm $(obj)/.x509.list)
+ endif
+ endif
+ 
+-kernel/modsign_certificate.o: $(obj)/x509_certificate_list
++kernel/system_certificates.o: $(obj)/x509_certificate_list
+ 
+ quiet_cmd_x509certs  = CERTS   $@
+-      cmd_x509certs  = cat $(X509_CERTIFICATES) /dev/null >$@
++      cmd_x509certs  = cat $(X509_CERTIFICATES) /dev/null >$@ $(foreach X509,$(X509_CERTIFICATES),; echo "  - Including cert $(X509)")
++
+ targets += $(obj)/x509_certificate_list
+ $(obj)/x509_certificate_list: $(X509_CERTIFICATES) $(obj)/.x509.list
+ 	$(call if_changed,x509certs)
+@@ -175,7 +178,9 @@ $(obj)/.x509.list:
+ 	@echo $(X509_CERTIFICATES) >$@
+ 
+ clean-files := x509_certificate_list .x509.list
++endif
+ 
++ifeq ($(CONFIG_MODULE_SIG),y)
+ ###############################################################################
+ #
+ # If module signing is requested, say by allyesconfig, but a key has not been
+diff --git a/kernel/modsign_certificate.S b/kernel/modsign_certificate.S
+deleted file mode 100644
+index 6fe03c7..0000000
+--- a/kernel/modsign_certificate.S
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#include <linux/export.h>
+-
+-#define GLOBAL(name)	\
+-	.globl VMLINUX_SYMBOL(name);	\
+-	VMLINUX_SYMBOL(name):
+-
+-	.section ".init.data","aw"
+-
+-GLOBAL(modsign_certificate_list)
+-	.incbin "kernel/x509_certificate_list"
+-GLOBAL(modsign_certificate_list_end)
+diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
+deleted file mode 100644
+index 2b6e699..0000000
+--- a/kernel/modsign_pubkey.c
++++ /dev/null
+@@ -1,104 +0,0 @@
+-/* Public keys for module signature verification
+- *
+- * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
+- * Written by David Howells (dhowells at redhat.com)
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public Licence
+- * as published by the Free Software Foundation; either version
+- * 2 of the Licence, or (at your option) any later version.
+- */
+-
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/cred.h>
+-#include <linux/err.h>
+-#include <keys/asymmetric-type.h>
+-#include "module-internal.h"
+-
+-struct key *modsign_keyring;
+-
+-extern __initdata const u8 modsign_certificate_list[];
+-extern __initdata const u8 modsign_certificate_list_end[];
+-
+-/*
+- * We need to make sure ccache doesn't cache the .o file as it doesn't notice
+- * if modsign.pub changes.
+- */
+-static __initdata const char annoy_ccache[] = __TIME__ "foo";
+-
+-/*
+- * Load the compiled-in keys
+- */
+-static __init int module_verify_init(void)
+-{
+-	pr_notice("Initialise module verification\n");
+-
+-	modsign_keyring = keyring_alloc(".module_sign",
+-					KUIDT_INIT(0), KGIDT_INIT(0),
+-					current_cred(),
+-					((KEY_POS_ALL & ~KEY_POS_SETATTR) |
+-					 KEY_USR_VIEW | KEY_USR_READ),
+-					KEY_ALLOC_NOT_IN_QUOTA, NULL);
+-	if (IS_ERR(modsign_keyring))
+-		panic("Can't allocate module signing keyring\n");
+-
+-	return 0;
+-}
+-
+-/*
+- * Must be initialised before we try and load the keys into the keyring.
+- */
+-device_initcall(module_verify_init);
+-
+-/*
+- * Load the compiled-in keys
+- */
+-static __init int load_module_signing_keys(void)
+-{
+-	key_ref_t key;
+-	const u8 *p, *end;
+-	size_t plen;
+-
+-	pr_notice("Loading module verification certificates\n");
+-
+-	end = modsign_certificate_list_end;
+-	p = modsign_certificate_list;
+-	while (p < end) {
+-		/* Each cert begins with an ASN.1 SEQUENCE tag and must be more
+-		 * than 256 bytes in size.
+-		 */
+-		if (end - p < 4)
+-			goto dodgy_cert;
+-		if (p[0] != 0x30 &&
+-		    p[1] != 0x82)
+-			goto dodgy_cert;
+-		plen = (p[2] << 8) | p[3];
+-		plen += 4;
+-		if (plen > end - p)
+-			goto dodgy_cert;
+-
+-		key = key_create_or_update(make_key_ref(modsign_keyring, 1),
+-					   "asymmetric",
+-					   NULL,
+-					   p,
+-					   plen,
+-					   (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+-					   KEY_USR_VIEW,
+-					   KEY_ALLOC_NOT_IN_QUOTA);
+-		if (IS_ERR(key))
+-			pr_err("MODSIGN: Problem loading in-kernel X.509 certificate (%ld)\n",
+-			       PTR_ERR(key));
+-		else
+-			pr_notice("MODSIGN: Loaded cert '%s'\n",
+-				  key_ref_to_ptr(key)->description);
+-		p += plen;
+-	}
+-
+-	return 0;
+-
+-dodgy_cert:
+-	pr_err("MODSIGN: Problem parsing in-kernel X.509 certificate list\n");
+-	return 0;
+-}
+-late_initcall(load_module_signing_keys);
+diff --git a/kernel/module-internal.h b/kernel/module-internal.h
+index 24f9247..915e123 100644
+--- a/kernel/module-internal.h
++++ b/kernel/module-internal.h
+@@ -9,6 +9,4 @@
+  * 2 of the Licence, or (at your option) any later version.
+  */
+ 
+-extern struct key *modsign_keyring;
+-
+ extern int mod_verify_sig(const void *mod, unsigned long *_modlen);
+diff --git a/kernel/module_signing.c b/kernel/module_signing.c
+index f2970bd..0034e36 100644
+--- a/kernel/module_signing.c
++++ b/kernel/module_signing.c
+@@ -14,6 +14,7 @@
+ #include <crypto/public_key.h>
+ #include <crypto/hash.h>
+ #include <keys/asymmetric-type.h>
++#include <keys/system_keyring.h>
+ #include "module-internal.h"
+ 
+ /*
+@@ -157,7 +158,7 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
+ 
+ 	pr_debug("Look up: \"%s\"\n", id);
+ 
+-	key = keyring_search(make_key_ref(modsign_keyring, 1),
++	key = keyring_search(make_key_ref(system_trusted_keyring, 1),
+ 			     &key_type_asymmetric, id);
+ 	if (IS_ERR(key))
+ 		pr_warn("Request for unknown module key '%s' err %ld\n",
+diff --git a/kernel/system_certificates.S b/kernel/system_certificates.S
+new file mode 100644
+index 0000000..5cffe86
+--- /dev/null
++++ b/kernel/system_certificates.S
+@@ -0,0 +1,11 @@
++#include <linux/export.h>
++
++#define GLOBAL(name)	\
++	.globl VMLINUX_SYMBOL(name);	\
++	VMLINUX_SYMBOL(name):
++
++	.section ".init.data","aw"
++
++GLOBAL(system_certificate_list)
++	.incbin "kernel/x509_certificate_list"
++GLOBAL(system_certificate_list_end)
+diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c
+new file mode 100644
+index 0000000..cd5cd3f
+--- /dev/null
++++ b/kernel/system_keyring.c
+@@ -0,0 +1,103 @@
++/* System trusted keyring for trusted public keys
++ *
++ * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells at redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++#include <linux/export.h>
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/cred.h>
++#include <linux/err.h>
++#include <keys/asymmetric-type.h>
++#include <keys/system_keyring.h>
++#include "module-internal.h"
++
++struct key *system_trusted_keyring;
++EXPORT_SYMBOL_GPL(system_trusted_keyring);
++
++extern __initdata const u8 system_certificate_list[];
++extern __initdata const u8 system_certificate_list_end[];
++
++/*
++ * Load the compiled-in keys
++ */
++static __init int system_trusted_keyring_init(void)
++{
++	pr_notice("Initialise system trusted keyring\n");
++
++	system_trusted_keyring =
++		keyring_alloc(".system_keyring",
++			      KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
++			      ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
++			       KEY_USR_VIEW | KEY_USR_READ),
++			      KEY_ALLOC_NOT_IN_QUOTA, NULL);
++	if (IS_ERR(system_trusted_keyring))
++		panic("Can't allocate system trusted keyring\n");
++
++	return 0;
++}
++
++/*
++ * Must be initialised before we try and load the keys into the keyring.
++ */
++device_initcall(system_trusted_keyring_init);
++
++/*
++ * Load the compiled-in list of X.509 certificates.
++ */
++static __init int load_system_certificate_list(void)
++{
++	key_ref_t key;
++	const u8 *p, *end;
++	size_t plen;
++
++	pr_notice("Loading compiled-in X.509 certificates\n");
++
++	end = system_certificate_list_end;
++	p = system_certificate_list;
++	while (p < end) {
++		/* Each cert begins with an ASN.1 SEQUENCE tag and must be more
++		 * than 256 bytes in size.
++		 */
++		if (end - p < 4)
++			goto dodgy_cert;
++		if (p[0] != 0x30 &&
++		    p[1] != 0x82)
++			goto dodgy_cert;
++		plen = (p[2] << 8) | p[3];
++		plen += 4;
++		if (plen > end - p)
++			goto dodgy_cert;
++
++		key = key_create_or_update(make_key_ref(system_trusted_keyring, 1),
++					   "asymmetric",
++					   NULL,
++					   p,
++					   plen,
++					   (KEY_POS_ALL & ~KEY_POS_SETATTR) |
++					   KEY_USR_VIEW,
++					   KEY_ALLOC_NOT_IN_QUOTA);
++		if (IS_ERR(key)) {
++			pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
++			       PTR_ERR(key));
++		} else {
++			pr_notice("Loaded X.509 cert '%s'\n",
++				  key_ref_to_ptr(key)->description);
++			key_ref_put(key);
++		}
++		p += plen;
++	}
++
++	return 0;
++
++dodgy_cert:
++	pr_err("Problem parsing in-kernel X.509 certificate list\n");
++	return 0;
++}
++late_initcall(load_system_certificate_list);
+-- 
+1.8.3.1
+
+
+From 6f90d07a776d7babf30a3322dafd66c8c25db681 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:07:37 +0100
+Subject: [PATCH 04/14] KEYS: Add a 'trusted' flag and a 'trusted only' flag
+
+Add KEY_FLAG_TRUSTED to indicate that a key either comes from a trusted source
+or had a cryptographic signature chain that led back to a trusted key the
+kernel already possessed.
+
+Add KEY_FLAGS_TRUSTED_ONLY to indicate that a keyring will only accept links to
+keys marked with KEY_FLAGS_TRUSTED.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+---
+ include/linux/key-type.h | 1 +
+ include/linux/key.h      | 3 +++
+ kernel/system_keyring.c  | 4 +++-
+ security/keys/key.c      | 8 ++++++++
+ security/keys/keyring.c  | 4 ++++
+ 5 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/key-type.h b/include/linux/key-type.h
+index f58737b..a74c3a8 100644
+--- a/include/linux/key-type.h
++++ b/include/linux/key-type.h
+@@ -45,6 +45,7 @@ struct key_preparsed_payload {
+ 	const void	*data;		/* Raw data */
+ 	size_t		datalen;	/* Raw datalen */
+ 	size_t		quotalen;	/* Quota length for proposed payload */
++	bool		trusted;	/* True if key is trusted */
+ };
+ 
+ typedef int (*request_key_actor_t)(struct key_construction *key,
+diff --git a/include/linux/key.h b/include/linux/key.h
+index 010dbb6..80d6774 100644
+--- a/include/linux/key.h
++++ b/include/linux/key.h
+@@ -168,6 +168,8 @@ struct key {
+ #define KEY_FLAG_NEGATIVE	5	/* set if key is negative */
+ #define KEY_FLAG_ROOT_CAN_CLEAR	6	/* set if key can be cleared by root without permission */
+ #define KEY_FLAG_INVALIDATED	7	/* set if key has been invalidated */
++#define KEY_FLAG_TRUSTED	8	/* set if key is trusted */
++#define KEY_FLAG_TRUSTED_ONLY	9	/* set if keyring only accepts links to trusted keys */
+ 
+ 	/* the key type and key description string
+ 	 * - the desc is used to match a key against search criteria
+@@ -218,6 +220,7 @@ extern struct key *key_alloc(struct key_type *type,
+ #define KEY_ALLOC_IN_QUOTA	0x0000	/* add to quota, reject if would overrun */
+ #define KEY_ALLOC_QUOTA_OVERRUN	0x0001	/* add to quota, permit even if overrun */
+ #define KEY_ALLOC_NOT_IN_QUOTA	0x0002	/* not in quota */
++#define KEY_ALLOC_TRUSTED	0x0004	/* Key should be flagged as trusted */
+ 
+ extern void key_revoke(struct key *key);
+ extern void key_invalidate(struct key *key);
+diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c
+index cd5cd3f..4ca7072 100644
+--- a/kernel/system_keyring.c
++++ b/kernel/system_keyring.c
+@@ -40,6 +40,7 @@ static __init int system_trusted_keyring_init(void)
+ 	if (IS_ERR(system_trusted_keyring))
+ 		panic("Can't allocate system trusted keyring\n");
+ 
++	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
+ 	return 0;
+ }
+ 
+@@ -82,7 +83,8 @@ static __init int load_system_certificate_list(void)
+ 					   plen,
+ 					   (KEY_POS_ALL & ~KEY_POS_SETATTR) |
+ 					   KEY_USR_VIEW,
+-					   KEY_ALLOC_NOT_IN_QUOTA);
++					   KEY_ALLOC_NOT_IN_QUOTA |
++					   KEY_ALLOC_TRUSTED);
+ 		if (IS_ERR(key)) {
+ 			pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
+ 			       PTR_ERR(key));
+diff --git a/security/keys/key.c b/security/keys/key.c
+index a819b5c..d331ea9 100644
+--- a/security/keys/key.c
++++ b/security/keys/key.c
+@@ -300,6 +300,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
+ 
+ 	if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
+ 		key->flags |= 1 << KEY_FLAG_IN_QUOTA;
++	if (flags & KEY_ALLOC_TRUSTED)
++		key->flags |= 1 << KEY_FLAG_TRUSTED;
+ 
+ 	memset(&key->type_data, 0, sizeof(key->type_data));
+ 
+@@ -813,6 +815,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
+ 	prep.data = payload;
+ 	prep.datalen = plen;
+ 	prep.quotalen = index_key.type->def_datalen;
++	prep.trusted = flags & KEY_ALLOC_TRUSTED;
+ 	if (index_key.type->preparse) {
+ 		ret = index_key.type->preparse(&prep);
+ 		if (ret < 0) {
+@@ -827,6 +830,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
+ 	}
+ 	index_key.desc_len = strlen(index_key.description);
+ 
++	key_ref = ERR_PTR(-EPERM);
++	if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags))
++		goto error_free_prep;
++	flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0;
++
+ 	ret = __key_link_begin(keyring, &index_key, &edit);
+ 	if (ret < 0) {
+ 		key_ref = ERR_PTR(ret);
+diff --git a/security/keys/keyring.c b/security/keys/keyring.c
+index f7cdea2..9b6f6e0 100644
+--- a/security/keys/keyring.c
++++ b/security/keys/keyring.c
+@@ -1183,6 +1183,10 @@ int key_link(struct key *keyring, struct key *key)
+ 	key_check(keyring);
+ 	key_check(key);
+ 
++	if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) &&
++	    !test_bit(KEY_FLAG_TRUSTED, &key->flags))
++		return -EPERM;
++
+ 	ret = __key_link_begin(keyring, &key->index_key, &edit);
+ 	if (ret == 0) {
+ 		kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));
+-- 
+1.8.3.1
+
+
+From 559cc3ad765e1b443bc89965be9ef9ff3caabdcc Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:15:10 +0100
+Subject: [PATCH 05/14] KEYS: Rename public key parameter name arrays
+
+Rename the arrays of public key parameters (public key algorithm names, hash
+algorithm names and ID type names) so that the array name ends in "_name".
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ crypto/asymmetric_keys/public_key.c      | 14 +++++++-------
+ crypto/asymmetric_keys/x509_public_key.c |  8 ++++----
+ include/crypto/public_key.h              |  6 +++---
+ kernel/module_signing.c                  |  4 ++--
+ 4 files changed, 16 insertions(+), 16 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
+index cb2e291..b313df1 100644
+--- a/crypto/asymmetric_keys/public_key.c
++++ b/crypto/asymmetric_keys/public_key.c
+@@ -22,13 +22,13 @@
+ 
+ MODULE_LICENSE("GPL");
+ 
+-const char *const pkey_algo[PKEY_ALGO__LAST] = {
++const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
+ 	[PKEY_ALGO_DSA]		= "DSA",
+ 	[PKEY_ALGO_RSA]		= "RSA",
+ };
+-EXPORT_SYMBOL_GPL(pkey_algo);
++EXPORT_SYMBOL_GPL(pkey_algo_name);
+ 
+-const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
++const char *const pkey_hash_algo_name[PKEY_HASH__LAST] = {
+ 	[PKEY_HASH_MD4]		= "md4",
+ 	[PKEY_HASH_MD5]		= "md5",
+ 	[PKEY_HASH_SHA1]	= "sha1",
+@@ -38,13 +38,13 @@ const char *const pkey_hash_algo[PKEY_HASH__LAST] = {
+ 	[PKEY_HASH_SHA512]	= "sha512",
+ 	[PKEY_HASH_SHA224]	= "sha224",
+ };
+-EXPORT_SYMBOL_GPL(pkey_hash_algo);
++EXPORT_SYMBOL_GPL(pkey_hash_algo_name);
+ 
+-const char *const pkey_id_type[PKEY_ID_TYPE__LAST] = {
++const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
+ 	[PKEY_ID_PGP]		= "PGP",
+ 	[PKEY_ID_X509]		= "X509",
+ };
+-EXPORT_SYMBOL_GPL(pkey_id_type);
++EXPORT_SYMBOL_GPL(pkey_id_type_name);
+ 
+ /*
+  * Provide a part of a description of the key for /proc/keys.
+@@ -56,7 +56,7 @@ static void public_key_describe(const struct key *asymmetric_key,
+ 
+ 	if (key)
+ 		seq_printf(m, "%s.%s",
+-			   pkey_id_type[key->id_type], key->algo->name);
++			   pkey_id_type_name[key->id_type], key->algo->name);
+ }
+ 
+ /*
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index 06007f0..afbbc36 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -49,7 +49,7 @@ static int x509_check_signature(const struct public_key *pub,
+ 	/* Allocate the hashing algorithm we're going to need and find out how
+ 	 * big the hash operational data will be.
+ 	 */
+-	tfm = crypto_alloc_shash(pkey_hash_algo[cert->sig_hash_algo], 0, 0);
++	tfm = crypto_alloc_shash(pkey_hash_algo_name[cert->sig_hash_algo], 0, 0);
+ 	if (IS_ERR(tfm))
+ 		return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
+ 
+@@ -117,7 +117,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 
+ 	pr_devel("Cert Issuer: %s\n", cert->issuer);
+ 	pr_devel("Cert Subject: %s\n", cert->subject);
+-	pr_devel("Cert Key Algo: %s\n", pkey_algo[cert->pkey_algo]);
++	pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pkey_algo]);
+ 	pr_devel("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
+ 		 cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1,
+ 		 cert->valid_from.tm_mday, cert->valid_from.tm_hour,
+@@ -127,8 +127,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 		 cert->valid_to.tm_mday, cert->valid_to.tm_hour,
+ 		 cert->valid_to.tm_min,  cert->valid_to.tm_sec);
+ 	pr_devel("Cert Signature: %s + %s\n",
+-		 pkey_algo[cert->sig_pkey_algo],
+-		 pkey_hash_algo[cert->sig_hash_algo]);
++		 pkey_algo_name[cert->sig_pkey_algo],
++		 pkey_hash_algo_name[cert->sig_hash_algo]);
+ 
+ 	if (!cert->fingerprint || !cert->authority) {
+ 		pr_warn("Cert for '%s' must have SubjKeyId and AuthKeyId extensions\n",
+diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
+index f5b0224..619d570 100644
+--- a/include/crypto/public_key.h
++++ b/include/crypto/public_key.h
+@@ -22,7 +22,7 @@ enum pkey_algo {
+ 	PKEY_ALGO__LAST
+ };
+ 
+-extern const char *const pkey_algo[PKEY_ALGO__LAST];
++extern const char *const pkey_algo_name[PKEY_ALGO__LAST];
+ 
+ enum pkey_hash_algo {
+ 	PKEY_HASH_MD4,
+@@ -36,7 +36,7 @@ enum pkey_hash_algo {
+ 	PKEY_HASH__LAST
+ };
+ 
+-extern const char *const pkey_hash_algo[PKEY_HASH__LAST];
++extern const char *const pkey_hash_algo_name[PKEY_HASH__LAST];
+ 
+ enum pkey_id_type {
+ 	PKEY_ID_PGP,		/* OpenPGP generated key ID */
+@@ -44,7 +44,7 @@ enum pkey_id_type {
+ 	PKEY_ID_TYPE__LAST
+ };
+ 
+-extern const char *const pkey_id_type[PKEY_ID_TYPE__LAST];
++extern const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST];
+ 
+ /*
+  * Cryptographic data for the public-key subtype of the asymmetric key type.
+diff --git a/kernel/module_signing.c b/kernel/module_signing.c
+index 0034e36..0b6b870 100644
+--- a/kernel/module_signing.c
++++ b/kernel/module_signing.c
+@@ -55,7 +55,7 @@ static struct public_key_signature *mod_make_digest(enum pkey_hash_algo hash,
+ 	/* Allocate the hashing algorithm we're going to need and find out how
+ 	 * big the hash operational data will be.
+ 	 */
+-	tfm = crypto_alloc_shash(pkey_hash_algo[hash], 0, 0);
++	tfm = crypto_alloc_shash(pkey_hash_algo_name[hash], 0, 0);
+ 	if (IS_ERR(tfm))
+ 		return (PTR_ERR(tfm) == -ENOENT) ? ERR_PTR(-ENOPKG) : ERR_CAST(tfm);
+ 
+@@ -218,7 +218,7 @@ int mod_verify_sig(const void *mod, unsigned long *_modlen)
+ 		return -ENOPKG;
+ 
+ 	if (ms.hash >= PKEY_HASH__LAST ||
+-	    !pkey_hash_algo[ms.hash])
++	    !pkey_hash_algo_name[ms.hash])
+ 		return -ENOPKG;
+ 
+ 	key = request_asymmetric_key(sig, ms.signer_len,
+-- 
+1.8.3.1
+
+
+From a0aab2065bbdd0bc56ae6d7767e1df7c58b8997f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:15:18 +0100
+Subject: [PATCH 06/14] KEYS: Move the algorithm pointer array from x509 to
+ public_key.c
+
+Move the public-key algorithm pointer array from x509_public_key.c to
+public_key.c as it isn't X.509 specific.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ crypto/asymmetric_keys/public_key.c      |  8 ++++++++
+ crypto/asymmetric_keys/x509_public_key.c | 11 +----------
+ include/crypto/public_key.h              |  1 +
+ 3 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
+index b313df1..796ce08 100644
+--- a/crypto/asymmetric_keys/public_key.c
++++ b/crypto/asymmetric_keys/public_key.c
+@@ -28,6 +28,14 @@ const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
+ };
+ EXPORT_SYMBOL_GPL(pkey_algo_name);
+ 
++const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = {
++#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
++	defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
++	[PKEY_ALGO_RSA]		= &RSA_public_key_algorithm,
++#endif
++};
++EXPORT_SYMBOL_GPL(pkey_algo);
++
+ const char *const pkey_hash_algo_name[PKEY_HASH__LAST] = {
+ 	[PKEY_HASH_MD4]		= "md4",
+ 	[PKEY_HASH_MD5]		= "md5",
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index afbbc36..fe38628 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -23,15 +23,6 @@
+ #include "public_key.h"
+ #include "x509_parser.h"
+ 
+-static const
+-struct public_key_algorithm *x509_public_key_algorithms[PKEY_ALGO__LAST] = {
+-	[PKEY_ALGO_DSA]		= NULL,
+-#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \
+-	defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE)
+-	[PKEY_ALGO_RSA]		= &RSA_public_key_algorithm,
+-#endif
+-};
+-
+ /*
+  * Check the signature on a certificate using the provided public key
+  */
+@@ -174,7 +165,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 		goto error_free_cert;
+ 	}
+ 
+-	cert->pub->algo = x509_public_key_algorithms[cert->pkey_algo];
++	cert->pub->algo = pkey_algo[cert->pkey_algo];
+ 	cert->pub->id_type = PKEY_ID_X509;
+ 
+ 	/* Check the signature on the key */
+diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
+index 619d570..46bde25 100644
+--- a/include/crypto/public_key.h
++++ b/include/crypto/public_key.h
+@@ -23,6 +23,7 @@ enum pkey_algo {
+ };
+ 
+ extern const char *const pkey_algo_name[PKEY_ALGO__LAST];
++extern const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST];
+ 
+ enum pkey_hash_algo {
+ 	PKEY_HASH_MD4,
+-- 
+1.8.3.1
+
+
+From 7009b65ddc1d8bf62dc017795265b9cf331a4d70 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:15:24 +0100
+Subject: [PATCH 07/14] KEYS: Store public key algo ID in public_key struct
+
+Store public key algo ID in public_key struct for reference purposes.  This
+allows it to be removed from the x509_certificate struct and used to find a
+default in public_key_verify_signature().
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ crypto/asymmetric_keys/x509_cert_parser.c | 5 +++--
+ crypto/asymmetric_keys/x509_parser.h      | 1 -
+ crypto/asymmetric_keys/x509_public_key.c  | 4 ++--
+ include/crypto/public_key.h               | 1 +
+ 4 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
+index facbf26..8cc253d 100644
+--- a/crypto/asymmetric_keys/x509_cert_parser.c
++++ b/crypto/asymmetric_keys/x509_cert_parser.c
+@@ -343,8 +343,9 @@ int x509_extract_key_data(void *context, size_t hdrlen,
+ 	if (ctx->last_oid != OID_rsaEncryption)
+ 		return -ENOPKG;
+ 
+-	/* There seems to be an extraneous 0 byte on the front of the data */
+-	ctx->cert->pkey_algo = PKEY_ALGO_RSA;
++	ctx->cert->pub->pkey_algo = PKEY_ALGO_RSA;
++
++	/* Discard the BIT STRING metadata */
+ 	ctx->key = value + 1;
+ 	ctx->key_size = vlen - 1;
+ 	return 0;
+diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
+index f86dc5f..e583ad0 100644
+--- a/crypto/asymmetric_keys/x509_parser.h
++++ b/crypto/asymmetric_keys/x509_parser.h
+@@ -20,7 +20,6 @@ struct x509_certificate {
+ 	char		*authority;		/* Authority key fingerprint as hex */
+ 	struct tm	valid_from;
+ 	struct tm	valid_to;
+-	enum pkey_algo	pkey_algo : 8;		/* Public key algorithm */
+ 	enum pkey_algo	sig_pkey_algo : 8;	/* Signature public key algorithm */
+ 	enum pkey_hash_algo sig_hash_algo : 8;	/* Signature hash algorithm */
+ 	const void	*tbs;			/* Signed data */
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index fe38628..fac574c 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -108,7 +108,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 
+ 	pr_devel("Cert Issuer: %s\n", cert->issuer);
+ 	pr_devel("Cert Subject: %s\n", cert->subject);
+-	pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pkey_algo]);
++	pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pub->pkey_algo]);
+ 	pr_devel("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
+ 		 cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1,
+ 		 cert->valid_from.tm_mday, cert->valid_from.tm_hour,
+@@ -165,7 +165,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 		goto error_free_cert;
+ 	}
+ 
+-	cert->pub->algo = pkey_algo[cert->pkey_algo];
++	cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
+ 	cert->pub->id_type = PKEY_ID_X509;
+ 
+ 	/* Check the signature on the key */
+diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
+index 46bde25..05778df 100644
+--- a/include/crypto/public_key.h
++++ b/include/crypto/public_key.h
+@@ -60,6 +60,7 @@ struct public_key {
+ #define PKEY_CAN_DECRYPT	0x02
+ #define PKEY_CAN_SIGN		0x04
+ #define PKEY_CAN_VERIFY		0x08
++	enum pkey_algo pkey_algo : 8;
+ 	enum pkey_id_type id_type : 8;
+ 	union {
+ 		MPI	mpi[5];
+-- 
+1.8.3.1
+
+
+From cad6ff6b429f31611ccb231cfe6adcb69d891352 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:15:30 +0100
+Subject: [PATCH 08/14] KEYS: Split public_key_verify_signature() and make
+ available
+
+Modify public_key_verify_signature() so that it now takes a public_key struct
+rather than a key struct and supply a wrapper that takes a key struct.  The
+wrapper is then used by the asymmetric key subtype and the modified function is
+used by X.509 self-signature checking and can be used by other things also.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ crypto/asymmetric_keys/public_key.c      | 40 +++++++++++++++++++++++++-------
+ crypto/asymmetric_keys/public_key.h      |  6 +++++
+ crypto/asymmetric_keys/x509_public_key.c |  2 +-
+ 3 files changed, 39 insertions(+), 9 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
+index 796ce08..49ac8d8 100644
+--- a/crypto/asymmetric_keys/public_key.c
++++ b/crypto/asymmetric_keys/public_key.c
+@@ -86,21 +86,45 @@ EXPORT_SYMBOL_GPL(public_key_destroy);
+ /*
+  * Verify a signature using a public key.
+  */
+-static int public_key_verify_signature(const struct key *key,
+-				       const struct public_key_signature *sig)
++int public_key_verify_signature(const struct public_key *pk,
++				const struct public_key_signature *sig)
+ {
+-	const struct public_key *pk = key->payload.data;
++	const struct public_key_algorithm *algo;
++
++	BUG_ON(!pk);
++	BUG_ON(!pk->mpi[0]);
++	BUG_ON(!pk->mpi[1]);
++	BUG_ON(!sig);
++	BUG_ON(!sig->digest);
++	BUG_ON(!sig->mpi[0]);
++
++	algo = pk->algo;
++	if (!algo) {
++		if (pk->pkey_algo >= PKEY_ALGO__LAST)
++			return -ENOPKG;
++		algo = pkey_algo[pk->pkey_algo];
++		if (!algo)
++			return -ENOPKG;
++	}
+ 
+-	if (!pk->algo->verify_signature)
++	if (!algo->verify_signature)
+ 		return -ENOTSUPP;
+ 
+-	if (sig->nr_mpi != pk->algo->n_sig_mpi) {
++	if (sig->nr_mpi != algo->n_sig_mpi) {
+ 		pr_debug("Signature has %u MPI not %u\n",
+-			 sig->nr_mpi, pk->algo->n_sig_mpi);
++			 sig->nr_mpi, algo->n_sig_mpi);
+ 		return -EINVAL;
+ 	}
+ 
+-	return pk->algo->verify_signature(pk, sig);
++	return algo->verify_signature(pk, sig);
++}
++EXPORT_SYMBOL_GPL(public_key_verify_signature);
++
++static int public_key_verify_signature_2(const struct key *key,
++					 const struct public_key_signature *sig)
++{
++	const struct public_key *pk = key->payload.data;
++	return public_key_verify_signature(pk, sig);
+ }
+ 
+ /*
+@@ -111,6 +135,6 @@ struct asymmetric_key_subtype public_key_subtype = {
+ 	.name			= "public_key",
+ 	.describe		= public_key_describe,
+ 	.destroy		= public_key_destroy,
+-	.verify_signature	= public_key_verify_signature,
++	.verify_signature	= public_key_verify_signature_2,
+ };
+ EXPORT_SYMBOL_GPL(public_key_subtype);
+diff --git a/crypto/asymmetric_keys/public_key.h b/crypto/asymmetric_keys/public_key.h
+index 5e5e356..5c37a22 100644
+--- a/crypto/asymmetric_keys/public_key.h
++++ b/crypto/asymmetric_keys/public_key.h
+@@ -28,3 +28,9 @@ struct public_key_algorithm {
+ };
+ 
+ extern const struct public_key_algorithm RSA_public_key_algorithm;
++
++/*
++ * public_key.c
++ */
++extern int public_key_verify_signature(const struct public_key *pk,
++				       const struct public_key_signature *sig);
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index fac574c..8cb2f70 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -76,7 +76,7 @@ static int x509_check_signature(const struct public_key *pub,
+ 	if (ret < 0)
+ 		goto error_mpi;
+ 
+-	ret = pub->algo->verify_signature(pub, sig);
++	ret = public_key_verify_signature(pub, sig);
+ 
+ 	pr_debug("Cert Verification: %d\n", ret);
+ 
+-- 
+1.8.3.1
+
+
+From 87854340605a64fcc54109ea415d9e54c45e8533 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:15:37 +0100
+Subject: [PATCH 09/14] KEYS: Store public key algo ID in public_key_signature
+ struct
+
+Store public key algorithm ID in public_key_signature struct for reference
+purposes.  This allows a public_key_signature struct to be embedded in
+struct x509_certificate and other places more easily.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ include/crypto/public_key.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/crypto/public_key.h b/include/crypto/public_key.h
+index 05778df..b34fda4 100644
+--- a/include/crypto/public_key.h
++++ b/include/crypto/public_key.h
+@@ -90,6 +90,7 @@ struct public_key_signature {
+ 	u8 *digest;
+ 	u8 digest_size;			/* Number of bytes in digest */
+ 	u8 nr_mpi;			/* Occupancy of mpi[] */
++	enum pkey_algo pkey_algo : 8;
+ 	enum pkey_hash_algo pkey_hash_algo : 8;
+ 	union {
+ 		MPI mpi[2];
+-- 
+1.8.3.1
+
+
+From ae4684a05d87123de310b69c616922dc993694ca Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:16:34 +0100
+Subject: [PATCH 10/14] X.509: struct x509_certificate needs struct tm
+ declaring
+
+struct x509_certificate needs struct tm declaring by #inclusion of linux/time.h
+prior to its definition.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ crypto/asymmetric_keys/x509_parser.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
+index e583ad0..2d01182 100644
+--- a/crypto/asymmetric_keys/x509_parser.h
++++ b/crypto/asymmetric_keys/x509_parser.h
+@@ -9,6 +9,7 @@
+  * 2 of the Licence, or (at your option) any later version.
+  */
+ 
++#include <linux/time.h>
+ #include <crypto/public_key.h>
+ 
+ struct x509_certificate {
+-- 
+1.8.3.1
+
+
+From dacde6f44ebe5a5c89bd1a25b35b1b63c139b375 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:18:02 +0100
+Subject: [PATCH 11/14] X.509: Embed public_key_signature struct and create
+ filler function
+
+Embed a public_key_signature struct in struct x509_certificate, eliminating
+now unnecessary fields, and split x509_check_signature() to create a filler
+function for it that attaches a digest of the signed data and an MPI that
+represents the signature data.  x509_free_certificate() is then modified to
+deal with these.
+
+Whilst we're at it, export both x509_check_signature() and the new
+x509_get_sig_params().
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ crypto/asymmetric_keys/x509_cert_parser.c | 30 +++++------
+ crypto/asymmetric_keys/x509_parser.h      | 16 ++++--
+ crypto/asymmetric_keys/x509_public_key.c  | 83 +++++++++++++++++--------------
+ 3 files changed, 74 insertions(+), 55 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
+index 8cc253d..144201c 100644
+--- a/crypto/asymmetric_keys/x509_cert_parser.c
++++ b/crypto/asymmetric_keys/x509_cert_parser.c
+@@ -47,6 +47,8 @@ void x509_free_certificate(struct x509_certificate *cert)
+ 		kfree(cert->subject);
+ 		kfree(cert->fingerprint);
+ 		kfree(cert->authority);
++		kfree(cert->sig.digest);
++		mpi_free(cert->sig.rsa.s);
+ 		kfree(cert);
+ 	}
+ }
+@@ -152,33 +154,33 @@ int x509_note_pkey_algo(void *context, size_t hdrlen,
+ 		return -ENOPKG; /* Unsupported combination */
+ 
+ 	case OID_md4WithRSAEncryption:
+-		ctx->cert->sig_hash_algo = PKEY_HASH_MD5;
+-		ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
++		ctx->cert->sig.pkey_hash_algo = PKEY_HASH_MD5;
++		ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
+ 		break;
+ 
+ 	case OID_sha1WithRSAEncryption:
+-		ctx->cert->sig_hash_algo = PKEY_HASH_SHA1;
+-		ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
++		ctx->cert->sig.pkey_hash_algo = PKEY_HASH_SHA1;
++		ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
+ 		break;
+ 
+ 	case OID_sha256WithRSAEncryption:
+-		ctx->cert->sig_hash_algo = PKEY_HASH_SHA256;
+-		ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
++		ctx->cert->sig.pkey_hash_algo = PKEY_HASH_SHA256;
++		ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
+ 		break;
+ 
+ 	case OID_sha384WithRSAEncryption:
+-		ctx->cert->sig_hash_algo = PKEY_HASH_SHA384;
+-		ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
++		ctx->cert->sig.pkey_hash_algo = PKEY_HASH_SHA384;
++		ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
+ 		break;
+ 
+ 	case OID_sha512WithRSAEncryption:
+-		ctx->cert->sig_hash_algo = PKEY_HASH_SHA512;
+-		ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
++		ctx->cert->sig.pkey_hash_algo = PKEY_HASH_SHA512;
++		ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
+ 		break;
+ 
+ 	case OID_sha224WithRSAEncryption:
+-		ctx->cert->sig_hash_algo = PKEY_HASH_SHA224;
+-		ctx->cert->sig_pkey_algo = PKEY_ALGO_RSA;
++		ctx->cert->sig.pkey_hash_algo = PKEY_HASH_SHA224;
++		ctx->cert->sig.pkey_algo = PKEY_ALGO_RSA;
+ 		break;
+ 	}
+ 
+@@ -203,8 +205,8 @@ int x509_note_signature(void *context, size_t hdrlen,
+ 		return -EINVAL;
+ 	}
+ 
+-	ctx->cert->sig = value;
+-	ctx->cert->sig_size = vlen;
++	ctx->cert->raw_sig = value;
++	ctx->cert->raw_sig_size = vlen;
+ 	return 0;
+ }
+ 
+diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
+index 2d01182..87d9cc2 100644
+--- a/crypto/asymmetric_keys/x509_parser.h
++++ b/crypto/asymmetric_keys/x509_parser.h
+@@ -21,12 +21,11 @@ struct x509_certificate {
+ 	char		*authority;		/* Authority key fingerprint as hex */
+ 	struct tm	valid_from;
+ 	struct tm	valid_to;
+-	enum pkey_algo	sig_pkey_algo : 8;	/* Signature public key algorithm */
+-	enum pkey_hash_algo sig_hash_algo : 8;	/* Signature hash algorithm */
+ 	const void	*tbs;			/* Signed data */
+-	size_t		tbs_size;		/* Size of signed data */
+-	const void	*sig;			/* Signature data */
+-	size_t		sig_size;		/* Size of sigature */
++	unsigned	tbs_size;		/* Size of signed data */
++	unsigned	raw_sig_size;		/* Size of sigature */
++	const void	*raw_sig;		/* Signature data */
++	struct public_key_signature sig;	/* Signature parameters */
+ };
+ 
+ /*
+@@ -34,3 +33,10 @@ struct x509_certificate {
+  */
+ extern void x509_free_certificate(struct x509_certificate *cert);
+ extern struct x509_certificate *x509_cert_parse(const void *data, size_t datalen);
++
++/*
++ * x509_public_key.c
++ */
++extern int x509_get_sig_params(struct x509_certificate *cert);
++extern int x509_check_signature(const struct public_key *pub,
++				struct x509_certificate *cert);
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index 8cb2f70..b7c81d8 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -24,72 +24,83 @@
+ #include "x509_parser.h"
+ 
+ /*
+- * Check the signature on a certificate using the provided public key
++ * Set up the signature parameters in an X.509 certificate.  This involves
++ * digesting the signed data and extracting the signature.
+  */
+-static int x509_check_signature(const struct public_key *pub,
+-				const struct x509_certificate *cert)
++int x509_get_sig_params(struct x509_certificate *cert)
+ {
+-	struct public_key_signature *sig;
+ 	struct crypto_shash *tfm;
+ 	struct shash_desc *desc;
+ 	size_t digest_size, desc_size;
++	void *digest;
+ 	int ret;
+ 
+ 	pr_devel("==>%s()\n", __func__);
+-	
++
++	if (cert->sig.rsa.s)
++		return 0;
++
++	cert->sig.rsa.s = mpi_read_raw_data(cert->raw_sig, cert->raw_sig_size);
++	if (!cert->sig.rsa.s)
++		return -ENOMEM;
++	cert->sig.nr_mpi = 1;
++
+ 	/* Allocate the hashing algorithm we're going to need and find out how
+ 	 * big the hash operational data will be.
+ 	 */
+-	tfm = crypto_alloc_shash(pkey_hash_algo_name[cert->sig_hash_algo], 0, 0);
++	tfm = crypto_alloc_shash(pkey_hash_algo_name[cert->sig.pkey_hash_algo], 0, 0);
+ 	if (IS_ERR(tfm))
+ 		return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
+ 
+ 	desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ 	digest_size = crypto_shash_digestsize(tfm);
+ 
+-	/* We allocate the hash operational data storage on the end of our
+-	 * context data.
++	/* We allocate the hash operational data storage on the end of the
++	 * digest storage space.
+ 	 */
+ 	ret = -ENOMEM;
+-	sig = kzalloc(sizeof(*sig) + desc_size + digest_size, GFP_KERNEL);
+-	if (!sig)
+-		goto error_no_sig;
++	digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
++	if (!digest)
++		goto error;
+ 
+-	sig->pkey_hash_algo	= cert->sig_hash_algo;
+-	sig->digest		= (u8 *)sig + sizeof(*sig) + desc_size;
+-	sig->digest_size	= digest_size;
++	cert->sig.digest = digest;
++	cert->sig.digest_size = digest_size;
+ 
+-	desc = (void *)sig + sizeof(*sig);
+-	desc->tfm	= tfm;
+-	desc->flags	= CRYPTO_TFM_REQ_MAY_SLEEP;
++	desc = digest + digest_size;
++	desc->tfm = tfm;
++	desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+ 
+ 	ret = crypto_shash_init(desc);
+ 	if (ret < 0)
+ 		goto error;
++	might_sleep();
++	ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, digest);
++error:
++	crypto_free_shash(tfm);
++	pr_devel("<==%s() = %d\n", __func__, ret);
++	return ret;
++}
++EXPORT_SYMBOL_GPL(x509_get_sig_params);
+ 
+-	ret = -ENOMEM;
+-	sig->rsa.s = mpi_read_raw_data(cert->sig, cert->sig_size);
+-	if (!sig->rsa.s)
+-		goto error;
++/*
++ * Check the signature on a certificate using the provided public key
++ */
++int x509_check_signature(const struct public_key *pub,
++			 struct x509_certificate *cert)
++{
++	int ret;
+ 
+-	ret = crypto_shash_finup(desc, cert->tbs, cert->tbs_size, sig->digest);
+-	if (ret < 0)
+-		goto error_mpi;
++	pr_devel("==>%s()\n", __func__);
+ 
+-	ret = public_key_verify_signature(pub, sig);
++	ret = x509_get_sig_params(cert);
++	if (ret < 0)
++		return ret;
+ 
++	ret = public_key_verify_signature(pub, &cert->sig);
+ 	pr_debug("Cert Verification: %d\n", ret);
+-
+-error_mpi:
+-	mpi_free(sig->rsa.s);
+-error:
+-	kfree(sig);
+-error_no_sig:
+-	crypto_free_shash(tfm);
+-
+-	pr_devel("<==%s() = %d\n", __func__, ret);
+ 	return ret;
+ }
++EXPORT_SYMBOL_GPL(x509_check_signature);
+ 
+ /*
+  * Attempt to parse a data blob for a key as an X509 certificate.
+@@ -118,8 +129,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 		 cert->valid_to.tm_mday, cert->valid_to.tm_hour,
+ 		 cert->valid_to.tm_min,  cert->valid_to.tm_sec);
+ 	pr_devel("Cert Signature: %s + %s\n",
+-		 pkey_algo_name[cert->sig_pkey_algo],
+-		 pkey_hash_algo_name[cert->sig_hash_algo]);
++		 pkey_algo_name[cert->sig.pkey_algo],
++		 pkey_hash_algo_name[cert->sig.pkey_hash_algo]);
+ 
+ 	if (!cert->fingerprint || !cert->authority) {
+ 		pr_warn("Cert for '%s' must have SubjKeyId and AuthKeyId extensions\n",
+-- 
+1.8.3.1
+
+
+From 650fdcb141f65f3a03dc7eba1179c823fd1a3a54 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:18:15 +0100
+Subject: [PATCH 12/14] X.509: Check the algorithm IDs obtained from parsing an
+ X.509 certificate
+
+Check that the algorithm IDs obtained from the ASN.1 parse by OID lookup
+corresponds to algorithms that are available to us.
+
+Reported-by: Kees Cook <keescook at chromium.org>
+Signed-off-by: David Howells <dhowells at redhat.com>
+---
+ crypto/asymmetric_keys/x509_public_key.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index b7c81d8..eb368d4 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -119,6 +119,17 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 
+ 	pr_devel("Cert Issuer: %s\n", cert->issuer);
+ 	pr_devel("Cert Subject: %s\n", cert->subject);
++
++	if (cert->pub->pkey_algo >= PKEY_ALGO__LAST ||
++	    cert->sig.pkey_algo >= PKEY_ALGO__LAST ||
++	    cert->sig.pkey_hash_algo >= PKEY_HASH__LAST ||
++	    !pkey_algo[cert->pub->pkey_algo] ||
++	    !pkey_algo[cert->sig.pkey_algo] ||
++	    !pkey_hash_algo_name[cert->sig.pkey_hash_algo]) {
++		ret = -ENOPKG;
++		goto error_free_cert;
++	}
++
+ 	pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pub->pkey_algo]);
+ 	pr_devel("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
+ 		 cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1,
+-- 
+1.8.3.1
+
+
+From 8671bdd55802c4b93b9205b6ecd02c7e351ac5c5 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Fri, 30 Aug 2013 16:18:31 +0100
+Subject: [PATCH 13/14] X.509: Handle certificates that lack an
+ authorityKeyIdentifier field
+
+Handle certificates that lack an authorityKeyIdentifier field by assuming
+they're self-signed and checking their signatures against themselves.
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+Reviewed-by: Kees Cook <keescook at chromium.org>
+Reviewed-by: Josh Boyer <jwboyer at redhat.com>
+---
+ crypto/asymmetric_keys/x509_public_key.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index eb368d4..0f55e3b 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -143,8 +143,8 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 		 pkey_algo_name[cert->sig.pkey_algo],
+ 		 pkey_hash_algo_name[cert->sig.pkey_hash_algo]);
+ 
+-	if (!cert->fingerprint || !cert->authority) {
+-		pr_warn("Cert for '%s' must have SubjKeyId and AuthKeyId extensions\n",
++	if (!cert->fingerprint) {
++		pr_warn("Cert for '%s' must have a SubjKeyId extension\n",
+ 			cert->subject);
+ 		ret = -EKEYREJECTED;
+ 		goto error_free_cert;
+@@ -190,8 +190,9 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 	cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
+ 	cert->pub->id_type = PKEY_ID_X509;
+ 
+-	/* Check the signature on the key */
+-	if (strcmp(cert->fingerprint, cert->authority) == 0) {
++	/* Check the signature on the key if it appears to be self-signed */
++	if (!cert->authority ||
++	    strcmp(cert->fingerprint, cert->authority) == 0) {
+ 		ret = x509_check_signature(cert->pub, cert);
+ 		if (ret < 0)
+ 			goto error_free_cert;
+-- 
+1.8.3.1
+
+
+From e2d665556f4b60ce76e880a62f98c81622271e71 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells at redhat.com>
+Date: Tue, 18 Jun 2013 17:40:44 +0100
+Subject: [PATCH 14/14] X.509: Remove certificate date checks
+
+Remove the certificate date checks that are performed when a certificate is
+parsed.  There are two checks: a valid from and a valid to.  The first check is
+causing a lot of problems with system clocks that don't keep good time and the
+second places an implicit expiry date upon the kernel when used for module
+signing, so do we really need them?
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+cc: David Woodhouse <dwmw2 at infradead.org>
+cc: Rusty Russell <rusty at rustcorp.com.au>
+cc: Josh Boyer <jwboyer at redhat.com>
+cc: Alexander Holler <holler at ahsoftware.de>
+cc: stable at vger.kernel.org
+---
+ crypto/asymmetric_keys/x509_public_key.c | 38 --------------------------------
+ 1 file changed, 38 deletions(-)
+
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index 0f55e3b..c1540e8 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -108,7 +108,6 @@ EXPORT_SYMBOL_GPL(x509_check_signature);
+ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ {
+ 	struct x509_certificate *cert;
+-	struct tm now;
+ 	size_t srlen, sulen;
+ 	char *desc = NULL;
+ 	int ret;
+@@ -150,43 +149,6 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 		goto error_free_cert;
+ 	}
+ 
+-	time_to_tm(CURRENT_TIME.tv_sec, 0, &now);
+-	pr_devel("Now: %04ld-%02d-%02d %02d:%02d:%02d\n",
+-		 now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
+-		 now.tm_hour, now.tm_min,  now.tm_sec);
+-	if (now.tm_year < cert->valid_from.tm_year ||
+-	    (now.tm_year == cert->valid_from.tm_year &&
+-	     (now.tm_mon < cert->valid_from.tm_mon ||
+-	      (now.tm_mon == cert->valid_from.tm_mon &&
+-	       (now.tm_mday < cert->valid_from.tm_mday ||
+-		(now.tm_mday == cert->valid_from.tm_mday &&
+-		 (now.tm_hour < cert->valid_from.tm_hour ||
+-		  (now.tm_hour == cert->valid_from.tm_hour &&
+-		   (now.tm_min < cert->valid_from.tm_min ||
+-		    (now.tm_min == cert->valid_from.tm_min &&
+-		     (now.tm_sec < cert->valid_from.tm_sec
+-		      ))))))))))) {
+-		pr_warn("Cert %s is not yet valid\n", cert->fingerprint);
+-		ret = -EKEYREJECTED;
+-		goto error_free_cert;
+-	}
+-	if (now.tm_year > cert->valid_to.tm_year ||
+-	    (now.tm_year == cert->valid_to.tm_year &&
+-	     (now.tm_mon > cert->valid_to.tm_mon ||
+-	      (now.tm_mon == cert->valid_to.tm_mon &&
+-	       (now.tm_mday > cert->valid_to.tm_mday ||
+-		(now.tm_mday == cert->valid_to.tm_mday &&
+-		 (now.tm_hour > cert->valid_to.tm_hour ||
+-		  (now.tm_hour == cert->valid_to.tm_hour &&
+-		   (now.tm_min > cert->valid_to.tm_min ||
+-		    (now.tm_min == cert->valid_to.tm_min &&
+-		     (now.tm_sec > cert->valid_to.tm_sec
+-		      ))))))))))) {
+-		pr_warn("Cert %s has expired\n", cert->fingerprint);
+-		ret = -EKEYEXPIRED;
+-		goto error_free_cert;
+-	}
+-
+ 	cert->pub->algo = pkey_algo[cert->pub->pkey_algo];
+ 	cert->pub->id_type = PKEY_ID_X509;
+ 
+-- 
+1.8.3.1
+
diff --git a/modsign-uefi.patch b/modsign-uefi.patch
index 3c043f6..c705260 100644
--- a/modsign-uefi.patch
+++ b/modsign-uefi.patch
@@ -1,4 +1,4 @@
-From cff9d37c9529fca5ff853f0050c7f0de0e819ea7 Mon Sep 17 00:00:00 2001
+From 725d7e7fb9ca1065102e640cf8af606169e63075 Mon Sep 17 00:00:00 2001
 From: Dave Howells <dhowells at redhat.com>
 Date: Tue, 23 Oct 2012 09:30:54 -0400
 Subject: [PATCH 1/4] Add EFI signature data types
@@ -53,7 +53,7 @@ index eed2202..1da1b3c 100644
 1.8.3.1
 
 
-From 2ce1c1d0d7110c4b06d65e4c8506f6c54aa72628 Mon Sep 17 00:00:00 2001
+From f204253a34b477c5d68df711326a694b58e51c76 Mon Sep 17 00:00:00 2001
 From: Dave Howells <dhowells at redhat.com>
 Date: Tue, 23 Oct 2012 09:36:28 -0400
 Subject: [PATCH 2/4] Add an EFI signature blob parser and key loader.
@@ -65,9 +65,9 @@ Signed-off-by: David Howells <dhowells at redhat.com>
 ---
  crypto/asymmetric_keys/Kconfig      |   8 +++
  crypto/asymmetric_keys/Makefile     |   1 +
- crypto/asymmetric_keys/efi_parser.c | 108 ++++++++++++++++++++++++++++++++++++
+ crypto/asymmetric_keys/efi_parser.c | 109 ++++++++++++++++++++++++++++++++++++
  include/linux/efi.h                 |   4 ++
- 4 files changed, 121 insertions(+)
+ 4 files changed, 122 insertions(+)
  create mode 100644 crypto/asymmetric_keys/efi_parser.c
 
 diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
@@ -101,10 +101,10 @@ index 0727204..cd8388e 100644
  # X.509 Certificate handling
 diff --git a/crypto/asymmetric_keys/efi_parser.c b/crypto/asymmetric_keys/efi_parser.c
 new file mode 100644
-index 0000000..636feb1
+index 0000000..424896a
 --- /dev/null
 +++ b/crypto/asymmetric_keys/efi_parser.c
-@@ -0,0 +1,108 @@
+@@ -0,0 +1,109 @@
 +/* EFI signature/key/certificate list parser
 + *
 + * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
@@ -195,7 +195,8 @@ index 0000000..636feb1
 +				esize - sizeof(*elem),
 +				(KEY_POS_ALL & ~KEY_POS_SETATTR) |
 +				KEY_USR_VIEW,
-+				KEY_ALLOC_NOT_IN_QUOTA);
++				KEY_ALLOC_NOT_IN_QUOTA |
++				KEY_ALLOC_TRUSTED);
 +
 +			if (IS_ERR(key))
 +				pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
@@ -232,10 +233,10 @@ index 1da1b3c..42a1d25 100644
 1.8.3.1
 
 
-From 0e4e8acfd0932bbf6b02112218092c810d9469a5 Mon Sep 17 00:00:00 2001
+From cebc8870a8f0b97b2585a07d9957ead0f21cdc8a Mon Sep 17 00:00:00 2001
 From: Josh Boyer <jwboyer at fedoraproject.org>
 Date: Fri, 26 Oct 2012 12:36:24 -0400
-Subject: [PATCH 3/4] MODSIGN: Add module certificate blacklist keyring
+Subject: [PATCH 3/4] KEYS: Add a system blacklist keyring
 
 This adds an additional keyring that is used to store certificates that
 are blacklisted.  This keyring is searched first when loading signed modules
@@ -244,86 +245,57 @@ useful in cases where third party certificates are used for module signing.
 
 Signed-off-by: Josh Boyer <jwboyer at fedoraproject.org>
 ---
- init/Kconfig             |  8 ++++++++
- kernel/modsign_pubkey.c  | 14 ++++++++++++++
- kernel/module-internal.h |  3 +++
- kernel/module_signing.c  | 12 ++++++++++++
- 4 files changed, 37 insertions(+)
+ include/keys/system_keyring.h |  4 ++++
+ init/Kconfig                  |  9 +++++++++
+ kernel/module_signing.c       | 12 ++++++++++++
+ kernel/system_keyring.c       | 17 +++++++++++++++++
+ 4 files changed, 42 insertions(+)
 
-diff --git a/init/Kconfig b/init/Kconfig
-index fed81b5..b4fa2d1 100644
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -1772,6 +1772,14 @@ config MODULE_SIG_ALL
- comment "Do not forget to sign required modules with scripts/sign-file"
- 	depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
- 
-+config MODULE_SIG_BLACKLIST
-+	bool "Support for blacklisting module signature certificates"
-+	depends on MODULE_SIG
-+	help
-+	  This adds support for keeping a blacklist of certificates that
-+	  should not pass module signature verification.  If a module is
-+	  signed with something in this keyring, the load will be rejected.
-+
- choice
- 	prompt "Which hash algorithm should modules be signed with?"
- 	depends on MODULE_SIG
-diff --git a/kernel/modsign_pubkey.c b/kernel/modsign_pubkey.c
-index 2b6e699..4cd408d 100644
---- a/kernel/modsign_pubkey.c
-+++ b/kernel/modsign_pubkey.c
-@@ -17,6 +17,9 @@
- #include "module-internal.h"
+diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
+index 8dabc39..e466de1 100644
+--- a/include/keys/system_keyring.h
++++ b/include/keys/system_keyring.h
+@@ -18,6 +18,10 @@
  
- struct key *modsign_keyring;
-+#ifdef CONFIG_MODULE_SIG_BLACKLIST
-+struct key *modsign_blacklist;
-+#endif
- 
- extern __initdata const u8 modsign_certificate_list[];
- extern __initdata const u8 modsign_certificate_list_end[];
-@@ -43,6 +46,17 @@ static __init int module_verify_init(void)
- 	if (IS_ERR(modsign_keyring))
- 		panic("Can't allocate module signing keyring\n");
+ extern struct key *system_trusted_keyring;
  
-+#ifdef CONFIG_MODULE_SIG_BLACKLIST
-+	modsign_blacklist = keyring_alloc(".modsign_blacklist",
-+				    KUIDT_INIT(0), KGIDT_INIT(0),
-+				    current_cred(),
-+				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
-+				    KEY_USR_VIEW | KEY_USR_READ,
-+				    KEY_ALLOC_NOT_IN_QUOTA, NULL);
-+	if (IS_ERR(modsign_blacklist))
-+		panic("Can't allocate module signing blacklist keyring\n");
++#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
++extern struct key *system_blacklist_keyring;
 +#endif
 +
- 	return 0;
- }
+ #endif
  
-diff --git a/kernel/module-internal.h b/kernel/module-internal.h
-index 24f9247..51a8380 100644
---- a/kernel/module-internal.h
-+++ b/kernel/module-internal.h
-@@ -10,5 +10,8 @@
-  */
+ #endif /* _KEYS_SYSTEM_KEYRING_H */
+diff --git a/init/Kconfig b/init/Kconfig
+index 9f3cfdc..547f617 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1676,6 +1676,15 @@ config SYSTEM_TRUSTED_KEYRING
  
- extern struct key *modsign_keyring;
-+#ifdef CONFIG_MODULE_SIG_BLACKLIST
-+extern struct key *modsign_blacklist;
-+#endif
+ 	  Keys in this keyring are used by module signature checking.
  
- extern int mod_verify_sig(const void *mod, unsigned long *_modlen);
++config SYSTEM_BLACKLIST_KEYRING
++	bool "Provide system-wide ring of blacklisted keys"
++	depends on KEYS
++	help
++	  Provide a system keyring to which blacklisted keys can be added.  Keys
++	  in the keyring are considered entirely untrusted.  Keys in this keyring
++	  are used by the module signature checking to reject loading of modules
++	  signed with a blacklisted key.
++
+ menuconfig MODULES
+ 	bool "Enable loadable module support"
+ 	help
 diff --git a/kernel/module_signing.c b/kernel/module_signing.c
-index f2970bd..5423195 100644
+index 0b6b870..0a29b40 100644
 --- a/kernel/module_signing.c
 +++ b/kernel/module_signing.c
-@@ -157,6 +157,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
+@@ -158,6 +158,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
  
  	pr_debug("Look up: \"%s\"\n", id);
  
-+#ifdef CONFIG_MODULE_SIG_BLACKLIST
-+	key = keyring_search(make_key_ref(modsign_blacklist, 1),
++#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
++	key = keyring_search(make_key_ref(system_blacklist_keyring, 1),
 +				   &key_type_asymmetric, id);
 +	if (!IS_ERR(key)) {
 +		/* module is signed with a cert in the blacklist.  reject */
@@ -334,20 +306,55 @@ index f2970bd..5423195 100644
 +	}
 +#endif
 +
- 	key = keyring_search(make_key_ref(modsign_keyring, 1),
+ 	key = keyring_search(make_key_ref(system_trusted_keyring, 1),
  			     &key_type_asymmetric, id);
  	if (IS_ERR(key))
+diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c
+index 4ca7072..b19cc6e 100644
+--- a/kernel/system_keyring.c
++++ b/kernel/system_keyring.c
+@@ -20,6 +20,9 @@
+ 
+ struct key *system_trusted_keyring;
+ EXPORT_SYMBOL_GPL(system_trusted_keyring);
++#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
++struct key *system_blacklist_keyring;
++#endif
+ 
+ extern __initdata const u8 system_certificate_list[];
+ extern __initdata const u8 system_certificate_list_end[];
+@@ -41,6 +44,20 @@ static __init int system_trusted_keyring_init(void)
+ 		panic("Can't allocate system trusted keyring\n");
+ 
+ 	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
++
++#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
++	system_blacklist_keyring = keyring_alloc(".system_blacklist_keyring",
++				    KUIDT_INIT(0), KGIDT_INIT(0),
++				    current_cred(),
++				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
++				    KEY_USR_VIEW | KEY_USR_READ,
++				    KEY_ALLOC_NOT_IN_QUOTA, NULL);
++	if (IS_ERR(system_blacklist_keyring))
++		panic("Can't allocate system blacklist keyring\n");
++
++	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_blacklist_keyring->flags);
++#endif
++
+ 	return 0;
+ }
+ 
 -- 
 1.8.3.1
 
 
-From c558b46370e850851a94795df67b7c57aecc48ea Mon Sep 17 00:00:00 2001
+From aa4f39ac51f8b9f589c13766e5e32a5b7794ed68 Mon Sep 17 00:00:00 2001
 From: Josh Boyer <jwboyer at fedoraproject.org>
 Date: Fri, 26 Oct 2012 12:42:16 -0400
 Subject: [PATCH 4/4] MODSIGN: Import certificates from UEFI Secure Boot
 
 Secure Boot stores a list of allowed certificates in the 'db' variable.
-This imports those certificates into the module signing keyring.  This
+This imports those certificates into the system trusted keyring.  This
 allows for a third party signing certificate to be used in conjunction
 with signed modules.  By importing the public certificate into the 'db'
 variable, a user can allow a module signed with that certificate to
@@ -356,7 +363,7 @@ in the 'MokListRT' variable.  We import those as well.
 
 In the opposite case, Secure Boot maintains a list of disallowed
 certificates in the 'dbx' variable.  We load those certificates into
-the newly introduced module blacklist keyring and forbid any module
+the newly introduced system blacklist keyring and forbid any module
 signed with those from loading.
 
 Signed-off-by: Josh Boyer <jwboyer at fedoraproject.org>
@@ -364,8 +371,8 @@ Signed-off-by: Josh Boyer <jwboyer at fedoraproject.org>
  include/linux/efi.h   |  6 ++++
  init/Kconfig          |  9 +++++
  kernel/Makefile       |  3 ++
- kernel/modsign_uefi.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
- 4 files changed, 109 insertions(+)
+ kernel/modsign_uefi.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 110 insertions(+)
  create mode 100644 kernel/modsign_uefi.c
 
 diff --git a/include/linux/efi.h b/include/linux/efi.h
@@ -386,16 +393,16 @@ index 42a1d25..d3e6036 100644
  	efi_guid_t guid;
  	u64 table;
 diff --git a/init/Kconfig b/init/Kconfig
-index b4fa2d1..94ce526 100644
+index 547f617..8e943bf 100644
 --- a/init/Kconfig
 +++ b/init/Kconfig
-@@ -1780,6 +1780,15 @@ config MODULE_SIG_BLACKLIST
- 	  should not pass module signature verification.  If a module is
- 	  signed with something in this keyring, the load will be rejected.
+@@ -1794,6 +1794,15 @@ config MODULE_SIG_ALL
+ comment "Do not forget to sign required modules with scripts/sign-file"
+ 	depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
  
 +config MODULE_SIG_UEFI
 +	bool "Allow modules signed with certs stored in UEFI"
-+	depends on MODULE_SIG && MODULE_SIG_BLACKLIST && EFI
++	depends on MODULE_SIG && SYSTEM_BLACKLIST_KEYRING && EFI
 +	select EFI_SIGNATURE_LIST_PARSER
 +	help
 +	  This will import certificates stored in UEFI and allow modules
@@ -406,18 +413,18 @@ index b4fa2d1..94ce526 100644
  	prompt "Which hash algorithm should modules be signed with?"
  	depends on MODULE_SIG
 diff --git a/kernel/Makefile b/kernel/Makefile
-index 35ef118..6ca1fea 100644
+index 1ff5e3b..f9b9998 100644
 --- a/kernel/Makefile
 +++ b/kernel/Makefile
-@@ -55,6 +55,7 @@ obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
- obj-$(CONFIG_UID16) += uid16.o
+@@ -56,6 +56,7 @@ obj-$(CONFIG_UID16) += uid16.o
+ obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
  obj-$(CONFIG_MODULES) += module.o
- obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o
+ obj-$(CONFIG_MODULE_SIG) += module_signing.o
 +obj-$(CONFIG_MODULE_SIG_UEFI) += modsign_uefi.o
  obj-$(CONFIG_KALLSYMS) += kallsyms.o
  obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
  obj-$(CONFIG_KEXEC) += kexec.o
-@@ -114,6 +115,8 @@ obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
+@@ -115,6 +116,8 @@ obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
  
  $(obj)/configs.o: $(obj)/config_data.h
  
@@ -428,10 +435,10 @@ index 35ef118..6ca1fea 100644
  targets += config_data.gz
 diff --git a/kernel/modsign_uefi.c b/kernel/modsign_uefi.c
 new file mode 100644
-index 0000000..7eae5b4
+index 0000000..94b0eb3
 --- /dev/null
 +++ b/kernel/modsign_uefi.c
-@@ -0,0 +1,91 @@
+@@ -0,0 +1,92 @@
 +#include <linux/kernel.h>
 +#include <linux/sched.h>
 +#include <linux/cred.h>
@@ -439,6 +446,7 @@ index 0000000..7eae5b4
 +#include <linux/efi.h>
 +#include <linux/slab.h>
 +#include <keys/asymmetric-type.h>
++#include <keys/system_keyring.h>
 +#include "module-internal.h"
 +
 +static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, unsigned long *size)
@@ -493,7 +501,7 @@ index 0000000..7eae5b4
 +	if (!db) {
 +		pr_err("MODSIGN: Couldn't get UEFI db list\n");
 +	} else {
-+		rc = parse_efi_signature_list(db, dbsize, modsign_keyring);
++		rc = parse_efi_signature_list(db, dbsize, system_trusted_keyring);
 +		if (rc)
 +			pr_err("Couldn't parse db signatures: %d\n", rc);
 +		kfree(db);
@@ -503,7 +511,7 @@ index 0000000..7eae5b4
 +	if (!mok) {
 +		pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
 +	} else {
-+		rc = parse_efi_signature_list(mok, moksize, modsign_keyring);
++		rc = parse_efi_signature_list(mok, moksize, system_trusted_keyring);
 +		if (rc)
 +			pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
 +		kfree(mok);
@@ -514,7 +522,7 @@ index 0000000..7eae5b4
 +		pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
 +	} else {
 +		rc = parse_efi_signature_list(dbx, dbxsize,
-+			modsign_blacklist);
++			system_blacklist_keyring);
 +		if (rc)
 +			pr_err("Couldn't parse dbx signatures: %d\n", rc);
 +		kfree(dbx);
diff --git a/sb-hibernate.patch b/sb-hibernate.patch
index 966024b..447237c 100644
--- a/sb-hibernate.patch
+++ b/sb-hibernate.patch
@@ -1,4 +1,4 @@
-From 4fe6d11d21b548d6e8272cc8cad5fcc6150ef081 Mon Sep 17 00:00:00 2001
+From ffe1ee94d526900ce1e5191cdd38934477dd209a Mon Sep 17 00:00:00 2001
 From: Josh Boyer <jwboyer at fedoraproject.org>
 Date: Fri, 26 Oct 2012 14:02:09 -0400
 Subject: [PATCH] hibernate: Disable in a signed modules environment
@@ -12,8 +12,8 @@ Signed-off-by: Josh Boyer <jwboyer at fedoraproject.com>
 ---
  kernel/power/hibernate.c | 16 +++++++++++++++-
  kernel/power/main.c      |  7 ++++++-
- kernel/power/user.c      |  5 +++++
- 3 files changed, 26 insertions(+), 2 deletions(-)
+ kernel/power/user.c      |  1 +
+ 3 files changed, 22 insertions(+), 2 deletions(-)
 
 diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
 index b26f5f1..e65228b 100644
@@ -96,28 +96,17 @@ index 1d1bf63..300f300 100644
  	if (s != buf)
  		/* convert the last space to a newline */
 diff --git a/kernel/power/user.c b/kernel/power/user.c
-index 4ed81e7..b714ee6 100644
+index 15cb72f..fa85ed5 100644
 --- a/kernel/power/user.c
 +++ b/kernel/power/user.c
-@@ -24,6 +24,8 @@
- #include <linux/console.h>
+@@ -25,6 +25,7 @@
  #include <linux/cpu.h>
  #include <linux/freezer.h>
+ #include <linux/module.h>
 +#include <linux/efi.h>
-+#include <linux/module.h>
  
  #include <asm/uaccess.h>
  
-@@ -48,6 +50,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
- 	struct snapshot_data *data;
- 	int error;
- 
-+	if (secure_modules())
-+		return -EPERM;
-+
- 	lock_system_sleep();
- 
- 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
 -- 
 1.8.3.1
 
diff --git a/secure-modules.patch b/secure-modules.patch
index d9beaa2..9d01b93 100644
--- a/secure-modules.patch
+++ b/secure-modules.patch
@@ -1,7 +1,7 @@
-From 17832506ee9b52bc8e00c2ec89b49257998171ed Mon Sep 17 00:00:00 2001
+From 8dea807503a1ba88d9e27595daae7f86ec968711 Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:02 -0400
-Subject: [PATCH 01/13] Add secure_modules() call
+Date: Fri, 9 Aug 2013 17:58:15 -0400
+Subject: [PATCH 01/14] Add secure_modules() call
 
 Provide a single call to allow kernel code to determine whether the system
 has been configured to either disable module loading entirely or to load
@@ -39,7 +39,7 @@ index 46f1ea0..0c266b2 100644
  
  #ifdef CONFIG_SYSFS
 diff --git a/kernel/module.c b/kernel/module.c
-index 2069158..499ee57 100644
+index 2069158..0e94acf 100644
 --- a/kernel/module.c
 +++ b/kernel/module.c
 @@ -3852,3 +3852,13 @@ void module_layout(struct module *mod,
@@ -55,15 +55,15 @@ index 2069158..499ee57 100644
 +	return modules_disabled;
 +#endif
 +}
-+EXPORT_SYMBOL_GPL(secure_modules);
++EXPORT_SYMBOL(secure_modules);
 -- 
 1.8.3.1
 
 
-From e347503648ace6a4b71dfb566365f1aa19657746 Mon Sep 17 00:00:00 2001
+From 9b7b3f6283bf784e4ea1c34e52646b12971b2823 Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:03 -0400
-Subject: [PATCH 02/13] PCI: Lock down BAR access when module security is
+Date: Thu, 8 Mar 2012 10:10:38 -0500
+Subject: [PATCH 02/14] PCI: Lock down BAR access when module security is
  enabled
 
 Any hardware that can potentially generate DMA has to be locked down from
@@ -179,10 +179,10 @@ index e1c1ec5..bffbf71 100644
 1.8.3.1
 
 
-From b846e3958d3f4ff875ec958efba8b681ccbae04e Mon Sep 17 00:00:00 2001
+From aac2425a2664c09c2a369e1eec6e7a5bc2713cb1 Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:04 -0400
-Subject: [PATCH 03/13] x86: Lock down IO port access when module security is
+Date: Thu, 8 Mar 2012 10:35:59 -0500
+Subject: [PATCH 03/14] x86: Lock down IO port access when module security is
  enabled
 
 IO port access would permit users to gain access to PCI configuration
@@ -252,10 +252,10 @@ index f895a8c..1af8664 100644
 1.8.3.1
 
 
-From 8c11e2cc989eece2d4978cfbc83f9b898f3cd1aa Mon Sep 17 00:00:00 2001
+From e7f9789c7eedf291972666befee726ff8e7126f6 Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:05 -0400
-Subject: [PATCH 04/13] ACPI: Limit access to custom_method
+Date: Fri, 9 Mar 2012 08:39:37 -0500
+Subject: [PATCH 04/14] ACPI: Limit access to custom_method
 
 custom_method effectively allows arbitrary access to system memory, making
 it possible for an attacker to circumvent restrictions on module loading.
@@ -263,22 +263,14 @@ Disable it if any such restrictions have been enabled.
 
 Signed-off-by: Matthew Garrett <matthew.garrett at nebula.com>
 ---
- drivers/acpi/custom_method.c | 4 ++++
- 1 file changed, 4 insertions(+)
+ drivers/acpi/custom_method.c | 3 +++
+ 1 file changed, 3 insertions(+)
 
 diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
-index 12b62f2..55a013f 100644
+index 12b62f2..50647b3 100644
 --- a/drivers/acpi/custom_method.c
 +++ b/drivers/acpi/custom_method.c
-@@ -7,6 +7,7 @@
- #include <linux/kernel.h>
- #include <linux/uaccess.h>
- #include <linux/debugfs.h>
-+#include <linux/module.h>
- #include <acpi/acpi_drivers.h>
- 
- #include "internal.h"
-@@ -29,6 +30,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
+@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
  	struct acpi_table_header table;
  	acpi_status status;
  
@@ -292,10 +284,10 @@ index 12b62f2..55a013f 100644
 1.8.3.1
 
 
-From 968ccfb32df5d5c9673c57641ebf90b25c0df880 Mon Sep 17 00:00:00 2001
+From d81cd6628c821d47bd086354cbc57b1474f3c1a8 Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:06 -0400
-Subject: [PATCH 05/13] asus-wmi: Restrict debugfs interface when module
+Date: Fri, 9 Mar 2012 08:46:50 -0500
+Subject: [PATCH 05/14] asus-wmi: Restrict debugfs interface when module
  loading is restricted
 
 We have no way of validating what all of the Asus WMI methods do on a
@@ -347,10 +339,10 @@ index 19c313b..db18ef66 100644
 1.8.3.1
 
 
-From e492d0a80bb591c34391757f97fc5aa8eb198e4f Mon Sep 17 00:00:00 2001
+From df75e984729ef50bb691b4d15472529fcd81580b Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:07 -0400
-Subject: [PATCH 06/13] Restrict /dev/mem and /dev/kmem when module loading is
+Date: Fri, 9 Mar 2012 09:28:15 -0500
+Subject: [PATCH 06/14] Restrict /dev/mem and /dev/kmem when module loading is
  restricted
 
 Allowing users to write to address space makes it possible for the kernel
@@ -390,10 +382,10 @@ index 1af8664..61406c8 100644
 1.8.3.1
 
 
-From 145913d656bfe8216032b38a576ac150699521e5 Mon Sep 17 00:00:00 2001
+From 78955913cc46cc5e5c7f2c71c1b07a5c18e06456 Mon Sep 17 00:00:00 2001
 From: Josh Boyer <jwboyer at redhat.com>
-Date: Mon, 19 Aug 2013 13:26:08 -0400
-Subject: [PATCH 07/13] acpi: Ignore acpi_rsdp kernel parameter when module
+Date: Mon, 25 Jun 2012 19:57:30 -0400
+Subject: [PATCH 07/14] acpi: Ignore acpi_rsdp kernel parameter when module
  loading is restricted
 
 This option allows userspace to pass the RSDP address to the kernel, which
@@ -430,10 +422,95 @@ index 6ab2c35..e4c4410 100644
 1.8.3.1
 
 
-From 012ac79f54ab746114d8276d8858a3df18b10e22 Mon Sep 17 00:00:00 2001
+From 23aae9143fbece326b3a26bf5ba48956c99cabe4 Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <matthew.garrett at nebula.com>
+Date: Fri, 9 Aug 2013 03:33:56 -0400
+Subject: [PATCH 08/14] kexec: Disable at runtime if the kernel enforces module
+ loading restrictions
+
+kexec permits the loading and execution of arbitrary code in ring 0, which
+is something that module signing enforcement is meant to prevent. It makes
+sense to disable kexec in this situation.
+
+Signed-off-by: Matthew Garrett <matthew.garrett at nebula.com>
+---
+ kernel/kexec.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/kernel/kexec.c b/kernel/kexec.c
+index 59f7b55..3e2b63a 100644
+--- a/kernel/kexec.c
++++ b/kernel/kexec.c
+@@ -32,6 +32,7 @@
+ #include <linux/vmalloc.h>
+ #include <linux/swap.h>
+ #include <linux/syscore_ops.h>
++#include <linux/module.h>
+ 
+ #include <asm/page.h>
+ #include <asm/uaccess.h>
+@@ -943,6 +944,13 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
+ 		return -EPERM;
+ 
+ 	/*
++	 * kexec can be used to circumvent module loading restrictions, so
++	 * prevent loading in that case
++	 */
++	if (secure_modules())
++		return -EPERM;
++
++	/*
+ 	 * Verify we have a legal set of flags
+ 	 * This leaves us room for future extensions.
+ 	 */
+-- 
+1.8.3.1
+
+
+From 218cd49aa2d6a085c5c4edc0396200864f0b54ad Mon Sep 17 00:00:00 2001
+From: Matthew Garrett <matthew.garrett at nebula.com>
+Date: Tue, 3 Sep 2013 11:23:29 -0400
+Subject: [PATCH 09/14] uswsusp: Disable when module loading is restricted
+
+uswsusp allows a user process to dump and then restore kernel state, which
+makes it possible to avoid module loading restrictions. Prevent this when
+any restrictions have been imposed on loading modules.
+
+Signed-off-by: Matthew Garrett <matthew.garrett at nebula.com>
+---
+ kernel/power/user.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/power/user.c b/kernel/power/user.c
+index 4ed81e7..15cb72f 100644
+--- a/kernel/power/user.c
++++ b/kernel/power/user.c
+@@ -24,6 +24,7 @@
+ #include <linux/console.h>
+ #include <linux/cpu.h>
+ #include <linux/freezer.h>
++#include <linux/module.h>
+ 
+ #include <asm/uaccess.h>
+ 
+@@ -48,6 +49,9 @@ static int snapshot_open(struct inode *inode, struct file *filp)
+ 	struct snapshot_data *data;
+ 	int error;
+ 
++	if (secure_modules())
++		return -EPERM;
++
+ 	lock_system_sleep();
+ 
+ 	if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
+-- 
+1.8.3.1
+
+
+From beeaac053d4ae57dc65be1da8b46e5d4bc6542b8 Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:10 -0400
-Subject: [PATCH 08/13] x86: Restrict MSR access when module loading is
+Date: Fri, 8 Feb 2013 11:12:13 -0800
+Subject: [PATCH 10/14] x86: Restrict MSR access when module loading is
  restricted
 
 Writing to MSRs should not be allowed if module loading is restricted,
@@ -475,51 +552,10 @@ index 88458fa..d08f7e3 100644
 1.8.3.1
 
 
-From a44d2968968fd667c8cbeba7c043f674d17e7ce7 Mon Sep 17 00:00:00 2001
-From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:09 -0400
-Subject: [PATCH 09/13] kexec: Disable at runtime if the kernel enforces module
- loading restrictions
-
-kexec permits the loading and execution of arbitrary code in ring 0, which
-is something that module signing enforcement is meant to prevent. It makes
-sense to disable kexec in this situation.
-
-Signed-off-by: Matthew Garrett <matthew.garrett at nebula.com>
----
- kernel/kexec.c | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/kernel/kexec.c b/kernel/kexec.c
-index 59f7b55..1a7690f 100644
---- a/kernel/kexec.c
-+++ b/kernel/kexec.c
-@@ -32,6 +32,7 @@
- #include <linux/vmalloc.h>
- #include <linux/swap.h>
- #include <linux/syscore_ops.h>
-+#include <linux/module.h>
- 
- #include <asm/page.h>
- #include <asm/uaccess.h>
-@@ -1645,6 +1646,9 @@ int kernel_kexec(void)
- 		goto Unlock;
- 	}
- 
-+	if (secure_modules())
-+		return -EPERM;
-+
- #ifdef CONFIG_KEXEC_JUMP
- 	if (kexec_image->preserve_context) {
- 		lock_system_sleep();
--- 
-1.8.3.1
-
-
-From f8f879da5dcc060a990a3b660aa5f340429cc4ed Mon Sep 17 00:00:00 2001
+From b4331711c52aff0a6a9cef0f4b52fe261874d6f2 Mon Sep 17 00:00:00 2001
 From: Matthew Garrett <matthew.garrett at nebula.com>
-Date: Mon, 19 Aug 2013 13:26:11 -0400
-Subject: [PATCH 10/13] Add option to automatically enforce module signatures
+Date: Fri, 9 Aug 2013 18:36:30 -0400
+Subject: [PATCH 11/14] Add option to automatically enforce module signatures
  when in Secure Boot mode
 
 UEFI Secure Boot provides a mechanism for ensuring that the firmware will
@@ -528,17 +564,15 @@ require that all kernel modules also be signed. Add a configuration option
 that enforces this automatically when enabled.
 
 Signed-off-by: Matthew Garrett <matthew.garrett at nebula.com>
-Signed-off-by: Josh Boyer <jwboyer at fedoraproject.org>
 ---
- Documentation/x86/zero-page.txt        |  2 ++
- arch/x86/Kconfig                       | 10 ++++++++++
- arch/x86/boot/compressed/eboot.c       | 33 +++++++++++++++++++++++++++++++++
- arch/x86/include/asm/bootparam_utils.h |  8 ++++++--
- arch/x86/include/uapi/asm/bootparam.h  |  3 ++-
- arch/x86/kernel/setup.c                |  6 ++++++
- include/linux/module.h                 |  6 ++++++
- kernel/module.c                        |  7 +++++++
- 8 files changed, 72 insertions(+), 3 deletions(-)
+ Documentation/x86/zero-page.txt       |  2 ++
+ arch/x86/Kconfig                      | 10 ++++++++++
+ arch/x86/boot/compressed/eboot.c      | 36 +++++++++++++++++++++++++++++++++++
+ arch/x86/include/uapi/asm/bootparam.h |  3 ++-
+ arch/x86/kernel/setup.c               |  6 ++++++
+ include/linux/module.h                |  6 ++++++
+ kernel/module.c                       |  7 +++++++
+ 7 files changed, 69 insertions(+), 1 deletion(-)
 
 diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
 index 199f453..ec38acf 100644
@@ -575,14 +609,22 @@ index b32ebf9..6a6c19b 100644
  	def_bool y
  	prompt "Enable seccomp to safely compute untrusted bytecode"
 diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
-index b7388a4..145294d 100644
+index b7388a4..53bfe4f 100644
 --- a/arch/x86/boot/compressed/eboot.c
 +++ b/arch/x86/boot/compressed/eboot.c
-@@ -861,6 +861,37 @@ fail:
+@@ -12,6 +12,7 @@
+ #include <asm/efi.h>
+ #include <asm/setup.h>
+ #include <asm/desc.h>
++#include <asm/bootparam_utils.h>
+ 
+ #undef memcpy			/* Use memcpy from misc.c */
+ 
+@@ -861,6 +862,37 @@ fail:
  	return status;
  }
  
-+static int get_secure_boot(efi_system_table_t *_table)
++static int get_secure_boot(void)
 +{
 +	u8 sb, setup;
 +	unsigned long datasize = sizeof(sb);
@@ -616,37 +658,19 @@ index b7388a4..145294d 100644
  /*
   * Because the x86 boot code expects to be passed a boot_params we
   * need to create one ourselves (usually the bootloader would create
-@@ -1169,6 +1200,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
+@@ -1169,6 +1201,10 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
  	if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE)
  		goto fail;
  
-+	boot_params->secure_boot = get_secure_boot(sys_table);
++	sanitize_boot_params(boot_params);
++
++	boot_params->secure_boot = get_secure_boot();
 +
  	setup_graphics(boot_params);
  
  	setup_efi_pci(boot_params);
-diff --git a/arch/x86/include/asm/bootparam_utils.h b/arch/x86/include/asm/bootparam_utils.h
-index 4a8cb8d..25f9cf1 100644
---- a/arch/x86/include/asm/bootparam_utils.h
-+++ b/arch/x86/include/asm/bootparam_utils.h
-@@ -38,9 +38,13 @@ static void sanitize_boot_params(struct boot_params *boot_params)
- 		memset(&boot_params->ext_ramdisk_image, 0,
- 		       (char *)&boot_params->efi_info -
- 			(char *)&boot_params->ext_ramdisk_image);
--		memset(&boot_params->kbd_status, 0,
-+		memset(&boot_params->kbd_status, 0, sizeof(boot_params->kbd_status));
-+		/* don't clear boot_params->secure_boot.  we set that ourselves
-+		 * earlier.
-+		 */
-+		memset(&boot_params->_pad5[0], 0,
- 		       (char *)&boot_params->hdr -
--		       (char *)&boot_params->kbd_status);
-+		       (char *)&boot_params->_pad5[0]);
- 		memset(&boot_params->_pad7[0], 0,
- 		       (char *)&boot_params->edd_mbr_sig_buffer[0] -
- 			(char *)&boot_params->_pad7[0]);
 diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
-index c15ddaf..d35da96 100644
+index c15ddaf..85d7685 100644
 --- a/arch/x86/include/uapi/asm/bootparam.h
 +++ b/arch/x86/include/uapi/asm/bootparam.h
 @@ -131,7 +131,8 @@ struct boot_params {
@@ -655,7 +679,7 @@ index c15ddaf..d35da96 100644
  	__u8  kbd_status;				/* 0x1eb */
 -	__u8  _pad5[3];					/* 0x1ec */
 +	__u8  secure_boot;				/* 0x1ec */
-+	__u8  _pad5[2];					/* 0x1ec */
++	__u8  _pad5[2];					/* 0x1ed */
  	/*
  	 * The sentinel is set to a nonzero value (0xff) in header.S.
  	 *
@@ -694,7 +718,7 @@ index 0c266b2..5a6374a 100644
  
  extern int modules_disabled; /* for sysctl */
 diff --git a/kernel/module.c b/kernel/module.c
-index 499ee57..bc7c987 100644
+index 0e94acf..974139b 100644
 --- a/kernel/module.c
 +++ b/kernel/module.c
 @@ -3853,6 +3853,13 @@ void module_layout(struct module *mod,
@@ -715,10 +739,10 @@ index 499ee57..bc7c987 100644
 1.8.3.1
 
 
-From b1604407fff69b17b598af03888a9efda0d58f2b Mon Sep 17 00:00:00 2001
+From bb28516d346e6511f1e012321c48eb142763e539 Mon Sep 17 00:00:00 2001
 From: Josh Boyer <jwboyer at redhat.com>
 Date: Tue, 5 Feb 2013 19:25:05 -0500
-Subject: [PATCH 11/13] efi: Disable secure boot if shim is in insecure mode
+Subject: [PATCH 12/14] efi: Disable secure boot if shim is in insecure mode
 
 A user can manually tell the shim boot loader to disable validation of
 images it loads.  When a user does this, it creates a UEFI variable called
@@ -732,12 +756,12 @@ Signed-off-by: Josh Boyer <jwboyer at redhat.com>
  1 file changed, 19 insertions(+), 1 deletion(-)
 
 diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
-index 145294d..545d4a6 100644
+index 53bfe4f..946028b 100644
 --- a/arch/x86/boot/compressed/eboot.c
 +++ b/arch/x86/boot/compressed/eboot.c
-@@ -863,8 +863,9 @@ fail:
+@@ -864,8 +864,9 @@ fail:
  
- static int get_secure_boot(efi_system_table_t *_table)
+ static int get_secure_boot(void)
  {
 -	u8 sb, setup;
 +	u8 sb, setup, moksbstate;
@@ -746,7 +770,7 @@ index 145294d..545d4a6 100644
  	efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID;
  	efi_status_t status;
  
-@@ -888,6 +889,23 @@ static int get_secure_boot(efi_system_table_t *_table)
+@@ -889,6 +890,23 @@ static int get_secure_boot(void)
  	if (setup == 1)
  		return 0;
  
@@ -774,10 +798,10 @@ index 145294d..545d4a6 100644
 1.8.3.1
 
 
-From 4d8b5cab923a2df15e1f33b3f0511366f9f98756 Mon Sep 17 00:00:00 2001
+From 4c8824bac8d4284e66c39c365ba84151f2d78e87 Mon Sep 17 00:00:00 2001
 From: Josh Boyer <jwboyer at fedoraproject.org>
 Date: Tue, 27 Aug 2013 13:28:43 -0400
-Subject: [PATCH 12/13] efi: Make EFI_SECURE_BOOT_SIG_ENFORCE depend on EFI
+Subject: [PATCH 13/14] efi: Make EFI_SECURE_BOOT_SIG_ENFORCE depend on EFI
 
 The functionality of the config option is dependent upon the platform being
 UEFI based.  Reflect this in the config deps.
@@ -805,10 +829,10 @@ index 6a6c19b..10498ec 100644
 1.8.3.1
 
 
-From a87ca6498b8a9f8e3c1d7e6ef7ef4e233ec8639d Mon Sep 17 00:00:00 2001
+From 871b0ed1847c3c5413a4ca72ecf18735858f7708 Mon Sep 17 00:00:00 2001
 From: Josh Boyer <jwboyer at fedoraproject.org>
 Date: Tue, 27 Aug 2013 13:33:03 -0400
-Subject: [PATCH 13/13] efi: Add EFI_SECURE_BOOT bit
+Subject: [PATCH 14/14] efi: Add EFI_SECURE_BOOT bit
 
 UEFI machines can be booted in Secure Boot mode.  Add a EFI_SECURE_BOOT bit
 for use with efi_enabled.


More information about the scm-commits mailing list