diff --git a/include/linux/key.h b/include/linux/key.h index 53684db4461560b5c933e56fcfa655f94e5e04df..61250dfd9ccc62151fe44e8706694fd40b93775f 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -272,6 +272,12 @@ struct key { * restriction. */ struct key_restriction *restrict_link; + + /* This is set on a keyring to indicate that every key added to this + * keyring should be tagged with a given key domain tag. It is ignored + * for the non-keyring keys and can be overridden by the key-type flags. + */ + unsigned long key_alloc_domain; }; extern struct key *key_alloc(struct key_type *type, @@ -291,6 +297,10 @@ extern struct key *key_alloc(struct key_type *type, #define KEY_ALLOC_UID_KEYRING 0x0010 /* allocating a user or user session keyring */ #define KEY_ALLOC_SET_KEEP 0x0020 /* Set the KEEP flag on the key/keyring */ +/* Only one domain can be set */ +#define KEY_ALLOC_DOMAIN_IMA 0x0100 /* add IMA domain tag, based on the "current" */ +#define KEY_ALLOC_DOMAIN_MASK 0xFF00 + extern void key_revoke(struct key *key); extern void key_invalidate(struct key *key); extern void key_put(struct key *key); diff --git a/security/keys/key.c b/security/keys/key.c index 151ff39b68030c4fe0bf9993843e41b1c80b264c..d052b9a0b1fdb3719b42029368993a454ca3f2c5 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -278,6 +278,19 @@ struct key *key_alloc(struct key_type *type, const char *desc, if (!key) goto no_memory_2; + if (flags & KEY_ALLOC_DOMAIN_MASK) { + /* set alloc domain for all keys added to this keyring */ + if (type == &key_type_keyring) + key->key_alloc_domain = (flags & KEY_ALLOC_DOMAIN_MASK); + + /* 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. + */ + key->index_key.domain_tag = NULL; + } + key->index_key.desc_len = desclen; key->index_key.description = kmemdup(desc, desclen + 1, GFP_KERNEL); if (!key->index_key.description) @@ -927,6 +940,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, perm |= KEY_POS_WRITE; } + if (keyring->key_alloc_domain) + flags |= keyring->key_alloc_domain; + /* allocate a new key */ key = key_alloc(index_key.type, index_key.description, cred->fsuid, cred->fsgid, cred, perm, flags, NULL);