From: Krzysztof Struczynski krzysztof.struczynski@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49KW1 CVE: NA
--------------------------------
Add key domain to the ima namespace. This will allow to bind the appraisal keys with the namespace and store all appraisal keys in the ima system keyring.
Signed-off-by: Krzysztof Struczynski krzysztof.struczynski@huawei.com Reviewed-by: Zhang Tianxing zhangtianxing3@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- include/linux/ima.h | 3 +++ security/integrity/ima/ima_init.c | 8 ++++++++ security/integrity/ima/ima_ns.c | 14 ++++++++++++++ security/keys/key.c | 10 +++++++--- 4 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/include/linux/ima.h b/include/linux/ima.h index 1270337c1d99..eb022229c694 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -237,6 +237,9 @@ struct ima_namespace { atomic_long_t violations; char *x509_path_for_children; struct ima_policy_setup_data *policy_setup_for_children; +#ifdef CONFIG_KEYS + struct key_tag *key_domain; +#endif } __randomize_layout;
extern struct ima_namespace init_ima_ns; diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 7a0a640fdf9c..73fb0f0e82c5 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -18,6 +18,7 @@ #include <linux/kref.h> #include <linux/proc_ns.h> #include <linux/user_namespace.h> +#include <linux/key.h>
#include "ima.h"
@@ -25,6 +26,10 @@ const char boot_aggregate_name[] = "boot_aggregate"; struct tpm_chip *ima_tpm_chip;
+#ifdef CONFIG_KEYS +static struct key_tag init_ima_key_domain = { .usage = REFCOUNT_INIT(1) }; +#endif + struct ima_namespace init_ima_ns = { .kref = KREF_INIT(2), .user_ns = &init_user_ns, @@ -40,6 +45,9 @@ struct ima_namespace init_ima_ns = { .ns_measurements = LIST_HEAD_INIT(init_ima_ns.ns_measurements), .ml_len = ATOMIC_LONG_INIT(0), .violations = ATOMIC_LONG_INIT(0), +#ifdef CONFIG_KEYS + .key_domain = &init_ima_key_domain, +#endif }; EXPORT_SYMBOL(init_ima_ns);
diff --git a/security/integrity/ima/ima_ns.c b/security/integrity/ima/ima_ns.c index 57dc9fedb8fd..639e5eadee31 100644 --- a/security/integrity/ima/ima_ns.c +++ b/security/integrity/ima/ima_ns.c @@ -29,6 +29,7 @@ #include <linux/spinlock.h> #include <linux/string.h> #include <linux/kernel.h> +#include <linux/key.h>
#include "ima.h"
@@ -66,8 +67,16 @@ static struct ima_namespace *ima_ns_alloc(void) if (!ima_ns->iint_tree) goto policy_free;
+#ifdef CONFIG_KEYS + ima_ns->key_domain = kzalloc(sizeof(struct key_tag), GFP_KERNEL); + if (!ima_ns->key_domain) + goto iint_free; +#endif + return ima_ns;
+iint_free: + kfree(ima_ns->iint_tree); policy_free: kfree(ima_ns->policy_data); ns_free: @@ -147,6 +156,9 @@ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns, rwlock_init(&ns->iint_tree->lock); ns->iint_tree->root = RB_ROOT;
+#ifdef CONFIG_KEYS + refcount_set(&ns->key_domain->usage, 1); +#endif ns->x509_path_for_children = NULL; ns->policy_setup_for_children = NULL;
@@ -160,6 +172,7 @@ static struct ima_namespace *clone_ima_ns(struct user_namespace *user_ns, fail_free: kfree(ns->iint_tree); kfree(ns->policy_data); + kfree(ns->key_domain); kfree(ns); fail_dec: dec_ima_namespaces(ucounts); @@ -231,6 +244,7 @@ static void destroy_ima_ns(struct ima_namespace *ns)
imans_remove_hash_entries(ns); dec_ima_namespaces(ns->ucounts); + key_remove_domain(ns->key_domain); put_user_ns(ns->user_ns); ns_free_inum(&ns->ns); integrity_iint_tree_free(ns->iint_tree); diff --git a/security/keys/key.c b/security/keys/key.c index d052b9a0b1fd..43de2dfe95cf 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -285,10 +285,14 @@ struct key *key_alloc(struct key_type *type, const char *desc,
/* set domain tag if it's not predefined for the key type */ if ((!type->flags) && (flags & KEY_ALLOC_DOMAIN_IMA)) - /* Set it to something meaningful after adding a key - * domain to the ima namespace. + /* Use ima_ns_for_children, not ima_ns. ima_ns_for + * children is equal to ima_ns, unless ima namespace was + * unshared and the new namespace is being configured. + * In that case, new keys should be associated with the + * new ima namespace. */ - key->index_key.domain_tag = NULL; + key->index_key.domain_tag = + current->nsproxy->ima_ns_for_children->key_domain; }
key->index_key.desc_len = desclen;