From: Krzysztof Struczynski <krzysztof.struczynski@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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 158028834747..7db4995c66cf 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -208,6 +208,9 @@ struct ima_namespace { char *policy_path_for_children; 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 d14c6689f422..1668edf3ed32 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, @@ -41,6 +46,9 @@ struct ima_namespace init_ima_ns = { .measurements = &ima_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 ec3abc803c82..872dc6a96a96 100644 --- a/security/integrity/ima/ima_ns.c +++ b/security/integrity/ima/ima_ns.c @@ -28,6 +28,7 @@ #include <linux/mutex.h> #include <linux/string.h> #include <linux/kernel.h> +#include <linux/key.h> #include "ima.h" @@ -65,8 +66,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: @@ -171,6 +180,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->policy_path_for_children = NULL; ns->x509_path_for_children = NULL; ns->policy_setup_for_children = NULL; @@ -184,6 +196,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); @@ -239,6 +252,7 @@ static void destroy_ima_ns(struct ima_namespace *ns) bool is_init_ns = (ns == &init_ima_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 1b0183d33bbc..fca0d12f5c71 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; -- 2.20.1