[PATCH 11/11] smack: Implement the watch_key and post_notification hooks [untested] [ver #7]

Casey Schaufler casey at schaufler-ca.com
Tue Sep 3 15:20:46 UTC 2019


On 8/30/2019 6:58 AM, David Howells wrote:
> Implement the watch_key security hook in Smack to make sure that a key
> grants the caller Read permission in order to set a watch on a key.
>
> Also implement the post_notification security hook to make sure that the
> notification source is granted Write permission by the watch queue.
>
> For the moment, the watch_devices security hook is left unimplemented as
> it's not obvious what the object should be since the queue is global and
> didn't previously exist.
>
> Signed-off-by: David Howells <dhowells at redhat.com>

I tried running your key tests and they fail in "keyctl/move/valid",
with 11 FAILED messages, finally hanging after "UNLINK KEY FROM SESSION".
It's possible that my Fedora26 system is somehow incompatible with the
tests. I don't see anything in your code that would cause this, as the
Smack policy on the system shouldn't restrict any access.

> ---
>
>  include/linux/lsm_audit.h  |    1 +
>  security/smack/smack_lsm.c |   82 +++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 82 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
> index 915330abf6e5..734d67889826 100644
> --- a/include/linux/lsm_audit.h
> +++ b/include/linux/lsm_audit.h
> @@ -74,6 +74,7 @@ struct common_audit_data {
>  #define LSM_AUDIT_DATA_FILE	12
>  #define LSM_AUDIT_DATA_IBPKEY	13
>  #define LSM_AUDIT_DATA_IBENDPORT 14
> +#define LSM_AUDIT_DATA_NOTIFICATION 15
>  	union 	{
>  		struct path path;
>  		struct dentry *dentry;
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 4c5e5a438f8b..1c2a908c6446 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -4274,7 +4274,7 @@ static int smack_key_permission(key_ref_t key_ref,
>  	if (tkp == NULL)
>  		return -EACCES;
>  
> -	if (smack_privileged_cred(CAP_MAC_OVERRIDE, cred))
> +	if (smack_privileged(CAP_MAC_OVERRIDE))
>  		return 0;
>  
>  #ifdef CONFIG_AUDIT
> @@ -4320,8 +4320,81 @@ static int smack_key_getsecurity(struct key *key, char **_buffer)
>  	return length;
>  }
>  
> +
> +#ifdef CONFIG_KEY_NOTIFICATIONS
> +/**
> + * smack_watch_key - Smack access to watch a key for notifications.
> + * @key: The key to be watched
> + *
> + * Return 0 if the @watch->cred has permission to read from the key object and
> + * an error otherwise.
> + */
> +static int smack_watch_key(struct key *key)
> +{
> +	struct smk_audit_info ad;
> +	struct smack_known *tkp = smk_of_current();
> +	int rc;
> +
> +	if (key == NULL)
> +		return -EINVAL;
> +	/*
> +	 * If the key hasn't been initialized give it access so that
> +	 * it may do so.
> +	 */
> +	if (key->security == NULL)
> +		return 0;
> +	/*
> +	 * This should not occur
> +	 */
> +	if (tkp == NULL)
> +		return -EACCES;
> +
> +	if (smack_privileged_cred(CAP_MAC_OVERRIDE, current_cred()))
> +		return 0;
> +
> +#ifdef CONFIG_AUDIT
> +	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_KEY);
> +	ad.a.u.key_struct.key = key->serial;
> +	ad.a.u.key_struct.key_desc = key->description;
> +#endif
> +	rc = smk_access(tkp, key->security, MAY_READ, &ad);
> +	rc = smk_bu_note("key watch", tkp, key->security, MAY_READ, rc);
> +	return rc;
> +}
> +#endif /* CONFIG_KEY_NOTIFICATIONS */
>  #endif /* CONFIG_KEYS */
>  
> +#ifdef CONFIG_WATCH_QUEUE
> +/**
> + * smack_post_notification - Smack access to post a notification to a queue
> + * @w_cred: The credentials of the watcher.
> + * @cred: The credentials of the event source (may be NULL).
> + * @n: The notification message to be posted.
> + */
> +static int smack_post_notification(const struct cred *w_cred,
> +				   const struct cred *cred,
> +				   struct watch_notification *n)
> +{
> +	struct smk_audit_info ad;
> +	struct smack_known *subj, *obj;
> +	int rc;
> +
> +	/* Always let maintenance notifications through. */
> +	if (n->type == WATCH_TYPE_META)
> +		return 0;
> +
> +	if (!cred)
> +		return 0;
> +	subj = smk_of_task(smack_cred(cred));
> +	obj = smk_of_task(smack_cred(w_cred));
> +
> +	smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_NOTIFICATION);
> +	rc = smk_access(subj, obj, MAY_WRITE, &ad);
> +	rc = smk_bu_note("notification", subj, obj, MAY_WRITE, rc);
> +	return rc;
> +}
> +#endif /* CONFIG_WATCH_QUEUE */
> +
>  /*
>   * Smack Audit hooks
>   *
> @@ -4710,8 +4783,15 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
>  	LSM_HOOK_INIT(key_free, smack_key_free),
>  	LSM_HOOK_INIT(key_permission, smack_key_permission),
>  	LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity),
> +#ifdef CONFIG_KEY_NOTIFICATIONS
> +	LSM_HOOK_INIT(watch_key, smack_watch_key),
> +#endif
>  #endif /* CONFIG_KEYS */
>  
> +#ifdef CONFIG_WATCH_QUEUE
> +	LSM_HOOK_INIT(post_notification, smack_post_notification),
> +#endif
> +
>   /* Audit hooks */
>  #ifdef CONFIG_AUDIT
>  	LSM_HOOK_INIT(audit_rule_init, smack_audit_rule_init),
>




More information about the Linux-security-module-archive mailing list