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