0f09adf
From: Josh Boyer <jwboyer@fedoraproject.org>
0f09adf
Date: Fri, 26 Oct 2012 12:36:24 -0400
0f09adf
Subject: [PATCH] KEYS: Add a system blacklist keyring
0f09adf
0f09adf
This adds an additional keyring that is used to store certificates that
0f09adf
are blacklisted.  This keyring is searched first when loading signed modules
0f09adf
and if the module's certificate is found, it will refuse to load.  This is
0f09adf
useful in cases where third party certificates are used for module signing.
0f09adf
0f09adf
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
0f09adf
---
0f09adf
 include/keys/system_keyring.h |  4 ++++
0f09adf
 init/Kconfig                  |  9 +++++++++
0f09adf
 kernel/module_signing.c       | 12 ++++++++++++
0f09adf
 kernel/system_keyring.c       | 17 +++++++++++++++++
0f09adf
 4 files changed, 42 insertions(+)
0f09adf
0f09adf
diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h
0f09adf
index 72665eb80692..2c7b80d31366 100644
0f09adf
--- a/include/keys/system_keyring.h
0f09adf
+++ b/include/keys/system_keyring.h
0f09adf
@@ -28,4 +28,8 @@ static inline struct key *get_system_trusted_keyring(void)
0f09adf
 }
0f09adf
 #endif
0f09adf
 
0f09adf
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
0f09adf
+extern struct key *system_blacklist_keyring;
0f09adf
+#endif
0f09adf
+
0f09adf
 #endif /* _KEYS_SYSTEM_KEYRING_H */
0f09adf
diff --git a/init/Kconfig b/init/Kconfig
0f09adf
index 80a6907f91c5..dfdd7f738247 100644
0f09adf
--- a/init/Kconfig
0f09adf
+++ b/init/Kconfig
0f09adf
@@ -1723,6 +1723,15 @@ config SYSTEM_TRUSTED_KEYRING
0f09adf
 
0f09adf
 	  Keys in this keyring are used by module signature checking.
0f09adf
 
0f09adf
+config SYSTEM_BLACKLIST_KEYRING
0f09adf
+	bool "Provide system-wide ring of blacklisted keys"
0f09adf
+	depends on KEYS
0f09adf
+	help
0f09adf
+	  Provide a system keyring to which blacklisted keys can be added.
0f09adf
+	  Keys in the keyring are considered entirely untrusted.  Keys in this
0f09adf
+	  keyring are used by the module signature checking to reject loading
0f09adf
+	  of modules signed with a blacklisted key.
0f09adf
+
0f09adf
 config PROFILING
0f09adf
 	bool "Profiling support"
0f09adf
 	help
0f09adf
diff --git a/kernel/module_signing.c b/kernel/module_signing.c
0f09adf
index be5b8fac4bd0..fed815fcdaf2 100644
0f09adf
--- a/kernel/module_signing.c
0f09adf
+++ b/kernel/module_signing.c
0f09adf
@@ -158,6 +158,18 @@ static struct key *request_asymmetric_key(const char *signer, size_t signer_len,
0f09adf
 
0f09adf
 	pr_debug("Look up: \"%s\"\n", id);
0f09adf
 
0f09adf
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
0f09adf
+	key = keyring_search(make_key_ref(system_blacklist_keyring, 1),
0f09adf
+				   &key_type_asymmetric, id);
0f09adf
+	if (!IS_ERR(key)) {
0f09adf
+		/* module is signed with a cert in the blacklist.  reject */
0f09adf
+		pr_err("Module key '%s' is in blacklist\n", id);
0f09adf
+		key_ref_put(key);
0f09adf
+		kfree(id);
0f09adf
+		return ERR_PTR(-EKEYREJECTED);
0f09adf
+	}
0f09adf
+#endif
0f09adf
+
0f09adf
 	key = keyring_search(make_key_ref(system_trusted_keyring, 1),
0f09adf
 			     &key_type_asymmetric, id);
0f09adf
 	if (IS_ERR(key))
0f09adf
diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c
0f09adf
index 875f64e8935b..c15e93f5a418 100644
0f09adf
--- a/kernel/system_keyring.c
0f09adf
+++ b/kernel/system_keyring.c
0f09adf
@@ -20,6 +20,9 @@
0f09adf
 
0f09adf
 struct key *system_trusted_keyring;
0f09adf
 EXPORT_SYMBOL_GPL(system_trusted_keyring);
0f09adf
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
0f09adf
+struct key *system_blacklist_keyring;
0f09adf
+#endif
0f09adf
 
0f09adf
 extern __initconst const u8 system_certificate_list[];
0f09adf
 extern __initconst const unsigned long system_certificate_list_size;
0f09adf
@@ -41,6 +44,20 @@ static __init int system_trusted_keyring_init(void)
0f09adf
 		panic("Can't allocate system trusted keyring\n");
0f09adf
 
0f09adf
 	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
0f09adf
+
0f09adf
+#ifdef CONFIG_SYSTEM_BLACKLIST_KEYRING
0f09adf
+	system_blacklist_keyring = keyring_alloc(".system_blacklist_keyring",
0f09adf
+				    KUIDT_INIT(0), KGIDT_INIT(0),
0f09adf
+				    current_cred(),
0f09adf
+				    (KEY_POS_ALL & ~KEY_POS_SETATTR) |
0f09adf
+				    KEY_USR_VIEW | KEY_USR_READ,
0f09adf
+				    KEY_ALLOC_NOT_IN_QUOTA, NULL);
0f09adf
+	if (IS_ERR(system_blacklist_keyring))
0f09adf
+		panic("Can't allocate system blacklist keyring\n");
0f09adf
+
0f09adf
+	set_bit(KEY_FLAG_TRUSTED_ONLY, &system_blacklist_keyring->flags);
0f09adf
+#endif
0f09adf
+
0f09adf
 	return 0;
0f09adf
 }
0f09adf
 
0f09adf
-- 
0f09adf
1.9.3
0f09adf