@@ -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;
@@ -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);
@@ -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);
@@ -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;