Commit b8d99703 authored by Roberto Sassu's avatar Roberto Sassu Committed by Paul Moore

security: Introduce key_post_create_or_update hook

In preparation for moving IMA and EVM to the LSM infrastructure, introduce
the key_post_create_or_update hook.

Depending on policy, IMA measures the key content after creation or update,
so that remote verifiers are aware of the operation.

Other LSMs could similarly take some action after successful key creation
or update.

The new hook cannot return an error and cannot cause the operation to be
reverted.
Signed-off-by: default avatarRoberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: default avatarStefan Berger <stefanb@linux.ibm.com>
Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Reviewed-by: default avatarMimi Zohar <zohar@linux.ibm.com>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 2d705d80
...@@ -405,6 +405,9 @@ LSM_HOOK(void, LSM_RET_VOID, key_free, struct key *key) ...@@ -405,6 +405,9 @@ LSM_HOOK(void, LSM_RET_VOID, key_free, struct key *key)
LSM_HOOK(int, 0, key_permission, key_ref_t key_ref, const struct cred *cred, LSM_HOOK(int, 0, key_permission, key_ref_t key_ref, const struct cred *cred,
enum key_need_perm need_perm) enum key_need_perm need_perm)
LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **buffer) LSM_HOOK(int, 0, key_getsecurity, struct key *key, char **buffer)
LSM_HOOK(void, LSM_RET_VOID, key_post_create_or_update, struct key *keyring,
struct key *key, const void *payload, size_t payload_len,
unsigned long flags, bool create)
#endif /* CONFIG_KEYS */ #endif /* CONFIG_KEYS */
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
......
...@@ -2004,6 +2004,9 @@ void security_key_free(struct key *key); ...@@ -2004,6 +2004,9 @@ void security_key_free(struct key *key);
int security_key_permission(key_ref_t key_ref, const struct cred *cred, int security_key_permission(key_ref_t key_ref, const struct cred *cred,
enum key_need_perm need_perm); enum key_need_perm need_perm);
int security_key_getsecurity(struct key *key, char **_buffer); int security_key_getsecurity(struct key *key, char **_buffer);
void security_key_post_create_or_update(struct key *keyring, struct key *key,
const void *payload, size_t payload_len,
unsigned long flags, bool create);
#else #else
...@@ -2031,6 +2034,14 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) ...@@ -2031,6 +2034,14 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer)
return 0; return 0;
} }
static inline void security_key_post_create_or_update(struct key *keyring,
struct key *key,
const void *payload,
size_t payload_len,
unsigned long flags,
bool create)
{ }
#endif #endif
#endif /* CONFIG_KEYS */ #endif /* CONFIG_KEYS */
......
...@@ -930,6 +930,8 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref, ...@@ -930,6 +930,8 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
goto error_link_end; goto error_link_end;
} }
security_key_post_create_or_update(keyring, key, payload, plen, flags,
true);
ima_post_key_create_or_update(keyring, key, payload, plen, ima_post_key_create_or_update(keyring, key, payload, plen,
flags, true); flags, true);
...@@ -963,10 +965,13 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref, ...@@ -963,10 +965,13 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref,
key_ref = __key_update(key_ref, &prep); key_ref = __key_update(key_ref, &prep);
if (!IS_ERR(key_ref)) if (!IS_ERR(key_ref)) {
security_key_post_create_or_update(keyring, key, payload, plen,
flags, false);
ima_post_key_create_or_update(keyring, key, ima_post_key_create_or_update(keyring, key,
payload, plen, payload, plen,
flags, false); flags, false);
}
goto error_free_prep; goto error_free_prep;
} }
......
...@@ -5453,6 +5453,25 @@ int security_key_getsecurity(struct key *key, char **buffer) ...@@ -5453,6 +5453,25 @@ int security_key_getsecurity(struct key *key, char **buffer)
*buffer = NULL; *buffer = NULL;
return call_int_hook(key_getsecurity, 0, key, buffer); return call_int_hook(key_getsecurity, 0, key, buffer);
} }
/**
* security_key_post_create_or_update() - Notification of key create or update
* @keyring: keyring to which the key is linked to
* @key: created or updated key
* @payload: data used to instantiate or update the key
* @payload_len: length of payload
* @flags: key flags
* @create: flag indicating whether the key was created or updated
*
* Notify the caller of a key creation or update.
*/
void security_key_post_create_or_update(struct key *keyring, struct key *key,
const void *payload, size_t payload_len,
unsigned long flags, bool create)
{
call_void_hook(key_post_create_or_update, keyring, key, payload,
payload_len, flags, create);
}
#endif /* CONFIG_KEYS */ #endif /* CONFIG_KEYS */
#ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment