Message ID | 20231107134012.682009-19-roberto.sassu@huaweicloud.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Paul Moore |
Headers | show |
Series | security: Move IMA and EVM to the LSM infrastructure | expand |
On 11/7/2023 5:40 AM, Roberto Sassu wrote: > From: Roberto Sassu <roberto.sassu@huawei.com> > > 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: Roberto Sassu <roberto.sassu@huawei.com> > Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Acked-by: Casey Schaufler <casey@schaufler-ca.com> > --- > include/linux/lsm_hook_defs.h | 3 +++ > include/linux/security.h | 11 +++++++++++ > security/keys/key.c | 7 ++++++- > security/security.c | 19 +++++++++++++++++++ > 4 files changed, 39 insertions(+), 1 deletion(-) > > diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h > index 2bf128f7cbae..ec5d160c32ba 100644 > --- a/include/linux/lsm_hook_defs.h > +++ b/include/linux/lsm_hook_defs.h > @@ -403,6 +403,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, > enum key_need_perm need_perm) > 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 */ > > #ifdef CONFIG_AUDIT > diff --git a/include/linux/security.h b/include/linux/security.h > index 7cd7126f6545..1cd84970ab4c 100644 > --- a/include/linux/security.h > +++ b/include/linux/security.h > @@ -1995,6 +1995,9 @@ void security_key_free(struct key *key); > int security_key_permission(key_ref_t key_ref, const struct cred *cred, > enum key_need_perm need_perm); > 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 > > @@ -2022,6 +2025,14 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) > 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 /* CONFIG_KEYS */ > > diff --git a/security/keys/key.c b/security/keys/key.c > index 0260a1902922..f75fe66c2f03 100644 > --- a/security/keys/key.c > +++ b/security/keys/key.c > @@ -935,6 +935,8 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref, > 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, > flags, true); > > @@ -968,10 +970,13 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref, > > 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, > payload, plen, > flags, false); > + } > > goto error_free_prep; > } > diff --git a/security/security.c b/security/security.c > index 6eb7c9cff1e5..859189722ab8 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -5406,6 +5406,25 @@ int security_key_getsecurity(struct key *key, char **buffer) > *buffer = NULL; > 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 */ > > #ifdef CONFIG_AUDIT
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 2bf128f7cbae..ec5d160c32ba 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -403,6 +403,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, enum key_need_perm need_perm) 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 */ #ifdef CONFIG_AUDIT diff --git a/include/linux/security.h b/include/linux/security.h index 7cd7126f6545..1cd84970ab4c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1995,6 +1995,9 @@ void security_key_free(struct key *key); int security_key_permission(key_ref_t key_ref, const struct cred *cred, enum key_need_perm need_perm); 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 @@ -2022,6 +2025,14 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) 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 /* CONFIG_KEYS */ diff --git a/security/keys/key.c b/security/keys/key.c index 0260a1902922..f75fe66c2f03 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -935,6 +935,8 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref, 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, flags, true); @@ -968,10 +970,13 @@ static key_ref_t __key_create_or_update(key_ref_t keyring_ref, 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, payload, plen, flags, false); + } goto error_free_prep; } diff --git a/security/security.c b/security/security.c index 6eb7c9cff1e5..859189722ab8 100644 --- a/security/security.c +++ b/security/security.c @@ -5406,6 +5406,25 @@ int security_key_getsecurity(struct key *key, char **buffer) *buffer = NULL; 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 */ #ifdef CONFIG_AUDIT