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