[RFC PATCH v3 06/13] clavis: Populate clavis keyring acl with kernel module signature

Eric Snowberg posted 13 patches 1 month, 1 week ago
[RFC PATCH v3 06/13] clavis: Populate clavis keyring acl with kernel module signature
Posted by Eric Snowberg 1 month, 1 week ago
If the kernel is built with CONFIG_MODULE_SIG_KEY, get the subject
key identifier and add an ACL for it within the .clavis keyring.

Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>
---
 certs/.gitignore                 |  1 +
 certs/Makefile                   | 20 ++++++++++++++++++++
 certs/clavis_module_acl.c        |  7 +++++++
 security/clavis/clavis.h         |  9 +++++++++
 security/clavis/clavis_keyring.c | 27 +++++++++++++++++++++++++++
 5 files changed, 64 insertions(+)
 create mode 100644 certs/clavis_module_acl.c

diff --git a/certs/.gitignore b/certs/.gitignore
index cec5465f31c1..dc99ae5a2585 100644
--- a/certs/.gitignore
+++ b/certs/.gitignore
@@ -3,3 +3,4 @@
 /extract-cert
 /x509_certificate_list
 /x509_revocation_list
+/module_acl
diff --git a/certs/Makefile b/certs/Makefile
index f6fa4d8d75e0..f2555e5296f5 100644
--- a/certs/Makefile
+++ b/certs/Makefile
@@ -6,6 +6,7 @@
 obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o system_certificates.o
 obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o blacklist_hashes.o
 obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o
+obj-$(CONFIG_SECURITY_CLAVIS) += clavis_module_acl.o
 
 $(obj)/blacklist_hashes.o: $(obj)/blacklist_hash_list
 CFLAGS_blacklist_hashes.o := -I $(obj)
@@ -75,6 +76,25 @@ $(obj)/signing_key.x509: $(filter-out $(PKCS11_URI),$(CONFIG_MODULE_SIG_KEY)) $(
 
 targets += signing_key.x509
 
+ifeq ($(CONFIG_MODULE_SIG_KEY),)
+quiet_cmd_make_module_acl = GEN   $@
+      cmd_make_module_acl = \
+	echo > $@
+else
+quiet_cmd_make_module_acl = GEN   $@
+      cmd_make_module_acl = \
+	openssl x509 -in $< -inform der -ext subjectKeyIdentifier  -nocert | \
+	tail -n +2 | cut -f2 -d '='| tr -d ':' | tr '[:upper:]' '[:lower:]' | \
+	sed 's/^[ \t]*//; s/.*/"00:&",/' > $@
+endif
+
+$(obj)/module_acl: $(obj)/signing_key.x509 FORCE
+		$(call if_changed,make_module_acl)
+
+$(obj)/clavis_module_acl.o: $(obj)/module_acl
+
+targets += module_acl
+
 $(obj)/revocation_certificates.o: $(obj)/x509_revocation_list
 
 $(obj)/x509_revocation_list: $(CONFIG_SYSTEM_REVOCATION_KEYS) $(obj)/extract-cert FORCE
diff --git a/certs/clavis_module_acl.c b/certs/clavis_module_acl.c
new file mode 100644
index 000000000000..fc2f694c48f9
--- /dev/null
+++ b/certs/clavis_module_acl.c
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kernel.h>
+
+const char __initconst *const clavis_module_acl[] = {
+#include "module_acl"
+	NULL
+};
diff --git a/security/clavis/clavis.h b/security/clavis/clavis.h
index 7b55a6050440..92f77a1939ad 100644
--- a/security/clavis/clavis.h
+++ b/security/clavis/clavis.h
@@ -11,4 +11,13 @@ struct asymmetric_setup_kid {
 	struct asymmetric_key_id id;
 	unsigned char data[CLAVIS_BIN_KID_MAX];
 };
+
+#ifndef CONFIG_SYSTEM_TRUSTED_KEYRING
+const char __initconst *const clavis_module_acl[] = {
+	 NULL
+};
+#else
+extern const char __initconst *const clavis_module_acl[];
+#endif
+
 #endif /* _SECURITY_CLAVIS_H_ */
diff --git a/security/clavis/clavis_keyring.c b/security/clavis/clavis_keyring.c
index 00163e7f0fe9..2a18d0e77189 100644
--- a/security/clavis/clavis_keyring.c
+++ b/security/clavis/clavis_keyring.c
@@ -259,6 +259,31 @@ static struct key_restriction *clavis_restriction_alloc(key_restrict_link_func_t
 	return restriction;
 }
 
+static void clavis_add_acl(const char *const *skid_list, struct key *keyring)
+{
+	const char *const *acl;
+	key_ref_t key;
+
+	for (acl = skid_list; *acl; acl++) {
+		key = key_create(make_key_ref(keyring, true),
+				 "clavis_key_acl",
+				  *acl,
+				  NULL,
+				  0,
+				  KEY_POS_SEARCH | KEY_POS_VIEW | KEY_USR_SEARCH | KEY_USR_VIEW,
+				  KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_BUILT_IN |
+				  KEY_ALLOC_BYPASS_RESTRICTION);
+		if (IS_ERR(key)) {
+			if (PTR_ERR(key) == -EEXIST)
+				pr_info("Duplicate clavis_key_acl %s\n", *acl);
+			else
+				pr_info("Problem with clavis_key_acl %s: %pe\n", *acl, key);
+		} else {
+			pr_info("Added clavis_key_acl %s\n", *acl);
+		}
+	}
+}
+
 static int __init clavis_keyring_init(void)
 {
 	struct key_restriction *restriction;
@@ -274,6 +299,8 @@ static int __init clavis_keyring_init(void)
 	if (IS_ERR(clavis_keyring))
 		panic("Can't allocate clavis keyring\n");
 
+	clavis_add_acl(clavis_module_acl, clavis_keyring);
+
 	return 0;
 }
 
-- 
2.45.0
Re: [RFC PATCH v3 06/13] clavis: Populate clavis keyring acl with kernel module signature
Posted by Jarkko Sakkinen 1 month, 1 week ago
On Thu, 2024-10-17 at 09:55 -0600, Eric Snowberg wrote:
> If the kernel is built with CONFIG_MODULE_SIG_KEY, get the subject
> key identifier and add an ACL for it within the .clavis keyring.
> 
> Signed-off-by: Eric Snowberg <eric.snowberg@oracle.com>

Super sound splits! Nice to review, have to give credit on this
:-)

> ---
>  certs/.gitignore                 |  1 +
>  certs/Makefile                   | 20 ++++++++++++++++++++
>  certs/clavis_module_acl.c        |  7 +++++++
>  security/clavis/clavis.h         |  9 +++++++++
>  security/clavis/clavis_keyring.c | 27 +++++++++++++++++++++++++++
>  5 files changed, 64 insertions(+)
>  create mode 100644 certs/clavis_module_acl.c
> 
> diff --git a/certs/.gitignore b/certs/.gitignore
> index cec5465f31c1..dc99ae5a2585 100644
> --- a/certs/.gitignore
> +++ b/certs/.gitignore
> @@ -3,3 +3,4 @@
>  /extract-cert
>  /x509_certificate_list
>  /x509_revocation_list
> +/module_acl
> diff --git a/certs/Makefile b/certs/Makefile
> index f6fa4d8d75e0..f2555e5296f5 100644
> --- a/certs/Makefile
> +++ b/certs/Makefile
> @@ -6,6 +6,7 @@
>  obj-$(CONFIG_SYSTEM_TRUSTED_KEYRING) += system_keyring.o
> system_certificates.o
>  obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist.o
> blacklist_hashes.o
>  obj-$(CONFIG_SYSTEM_REVOCATION_LIST) += revocation_certificates.o
> +obj-$(CONFIG_SECURITY_CLAVIS) += clavis_module_acl.o
>  
>  $(obj)/blacklist_hashes.o: $(obj)/blacklist_hash_list
>  CFLAGS_blacklist_hashes.o := -I $(obj)
> @@ -75,6 +76,25 @@ $(obj)/signing_key.x509: $(filter-out
> $(PKCS11_URI),$(CONFIG_MODULE_SIG_KEY)) $(
>  
>  targets += signing_key.x509
>  
> +ifeq ($(CONFIG_MODULE_SIG_KEY),)
> +quiet_cmd_make_module_acl = GEN   $@
> +      cmd_make_module_acl = \
> +	echo > $@
> +else
> +quiet_cmd_make_module_acl = GEN   $@
> +      cmd_make_module_acl = \
> +	openssl x509 -in $< -inform der -ext subjectKeyIdentifier  -
> nocert | \
> +	tail -n +2 | cut -f2 -d '='| tr -d ':' | tr '[:upper:]'
> '[:lower:]' | \
> +	sed 's/^[ \t]*//; s/.*/"00:&",/' > $@
> +endif
> +
> +$(obj)/module_acl: $(obj)/signing_key.x509 FORCE
> +		$(call if_changed,make_module_acl)
> +
> +$(obj)/clavis_module_acl.o: $(obj)/module_acl
> +
> +targets += module_acl
> +
>  $(obj)/revocation_certificates.o: $(obj)/x509_revocation_list
>  
>  $(obj)/x509_revocation_list: $(CONFIG_SYSTEM_REVOCATION_KEYS)
> $(obj)/extract-cert FORCE
> diff --git a/certs/clavis_module_acl.c b/certs/clavis_module_acl.c
> new file mode 100644
> index 000000000000..fc2f694c48f9
> --- /dev/null
> +++ b/certs/clavis_module_acl.c
> @@ -0,0 +1,7 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <linux/kernel.h>
> +
> +const char __initconst *const clavis_module_acl[] = {
> +#include "module_acl"
> +	NULL
> +};
> diff --git a/security/clavis/clavis.h b/security/clavis/clavis.h
> index 7b55a6050440..92f77a1939ad 100644
> --- a/security/clavis/clavis.h
> +++ b/security/clavis/clavis.h
> @@ -11,4 +11,13 @@ struct asymmetric_setup_kid {
>  	struct asymmetric_key_id id;
>  	unsigned char data[CLAVIS_BIN_KID_MAX];
>  };
> +
> +#ifndef CONFIG_SYSTEM_TRUSTED_KEYRING
> +const char __initconst *const clavis_module_acl[] = {
> +	 NULL
> +};
> +#else
> +extern const char __initconst *const clavis_module_acl[];
> +#endif
> +
>  #endif /* _SECURITY_CLAVIS_H_ */
> diff --git a/security/clavis/clavis_keyring.c
> b/security/clavis/clavis_keyring.c
> index 00163e7f0fe9..2a18d0e77189 100644
> --- a/security/clavis/clavis_keyring.c
> +++ b/security/clavis/clavis_keyring.c
> @@ -259,6 +259,31 @@ static struct key_restriction
> *clavis_restriction_alloc(key_restrict_link_func_t
>  	return restriction;
>  }
>  
> +static void clavis_add_acl(const char *const *skid_list, struct key
> *keyring)
> +{
> +	const char *const *acl;
> +	key_ref_t key;
> +
> +	for (acl = skid_list; *acl; acl++) {
> +		key = key_create(make_key_ref(keyring, true),
> +				 "clavis_key_acl",
> +				  *acl,
> +				  NULL,
> +				  0,
> +				  KEY_POS_SEARCH | KEY_POS_VIEW |
> KEY_USR_SEARCH | KEY_USR_VIEW,
> +				  KEY_ALLOC_NOT_IN_QUOTA |
> KEY_ALLOC_BUILT_IN |
> +				  KEY_ALLOC_BYPASS_RESTRICTION);
> +		if (IS_ERR(key)) {
> +			if (PTR_ERR(key) == -EEXIST)
> +				pr_info("Duplicate clavis_key_acl
> %s\n", *acl);
> +			else
> +				pr_info("Problem with clavis_key_acl
> %s: %pe\n", *acl, key);
> +		} else {
> +			pr_info("Added clavis_key_acl %s\n", *acl);
> +		}
> +	}
> +}
> +
>  static int __init clavis_keyring_init(void)
>  {
>  	struct key_restriction *restriction;
> @@ -274,6 +299,8 @@ static int __init clavis_keyring_init(void)
>  	if (IS_ERR(clavis_keyring))
>  		panic("Can't allocate clavis keyring\n");
>  
> +	clavis_add_acl(clavis_module_acl, clavis_keyring);
> +
>  	return 0;
>  }
>  

Not yet tagging, but neither anything to complain. LGTM

BR, Jarkko