Blob Blame History Raw
From 920108c0f9cc5854dd329a5dfc904e91d40a4b26 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@fedoraproject.org>
Date: Fri, 26 Oct 2012 12:36:24 -0400
Subject: KEYS: Add a system blacklist keyring

Patch-mainline: Not yet, from Fedora 20
References: fate#314574

This adds an additional keyring that is used to store certificates that
are blacklisted.  This keyring is searched first when loading signed
modules and if the module's certificate is found, it will refuse to
load.  This is useful in cases where third party certificates are used
for module signing.

Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
Acked-by: Lee, Chun-Yi <jlee@suse.com>
---
 certs/Kconfig                 |  9 +++++++++
 certs/system_keyring.c        | 17 +++++++++++++++++
 include/keys/system_keyring.h |  5 +++++
 kernel/module_signing.c       | 12 ++++++++++++
 4 files changed, 43 insertions(+)

diff --git a/certs/Kconfig b/certs/Kconfig
index b030b9c..47e0f28 100644
--- a/certs/Kconfig
+++ b/certs/Kconfig
@@ -26,6 +26,15 @@ config SYSTEM_TRUSTED_KEYRING
 
 	  Keys in this keyring are used by module signature checking.
 
+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.
+
 config SYSTEM_TRUSTED_KEYS
 	string "Additional X.509 keys for default system keyring"
 	depends on SYSTEM_TRUSTED_KEYRING
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index 2570598..6c5787c 100644
--- a/certs/system_keyring.c
+++ b/certs/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 __initconst const u8 system_certificate_list[];
 extern __initconst const unsigned long system_certificate_list_size;
@@ -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;
 }
 
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
index b20cd88..752f67f 100644
--- a/include/keys/system_keyring.h
+++ b/include/keys/system_keyring.h
@@ -22,6 +22,11 @@ static inline struct key *get_system_trusted_keyring(void)
 {
 	return system_trusted_keyring;
 }
+
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
+extern struct key *system_blacklist_keyring;
+#endif
+
 #else
 static inline struct key *get_system_trusted_keyring(void)
 {
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
index 48ede9f..15126ba 100644
--- a/kernel/module_signing.c
+++ b/kernel/module_signing.c
@@ -214,6 +214,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
 
 	pr_debug("Look up: \"%s\"\n", id);
 
+#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 */
+		pr_err("Module key '%s' is in blacklist\n", id);
+		key_ref_put(key);
+		kfree(id);
+		return ERR_PTR(-EKEYREJECTED);
+	}
+#endif
+
 	key = keyring_search(make_key_ref(system_trusted_keyring, 1),
 			     &key_type_asymmetric, id);
 	if (IS_ERR(key))
-- 
2.6.2