Linux Security Modules development
 help / color / mirror / Atom feed
From: John Johansen <john.johansen@canonical.com>
To: Casey Schaufler <casey@schaufler-ca.com>,
	paul@paul-moore.com, linux-security-module@vger.kernel.org
Cc: jmorris@namei.org, serge@hallyn.com, keescook@chromium.org,
	penguin-kernel@i-love.sakura.ne.jp,
	stephen.smalley.work@gmail.com, mic@digikod.net
Subject: Re: [PATCH v2 2/6] LSM: Infrastructure management of the key security blob
Date: Wed, 10 Jul 2024 15:45:52 -0700	[thread overview]
Message-ID: <8b0ae00d-6876-4f44-9e01-10d45550860a@canonical.com> (raw)
In-Reply-To: <20240710213230.11978-3-casey@schaufler-ca.com>

On 7/10/24 14:32, Casey Schaufler wrote:
> Move management of the key->security blob out of the individual security
> modules and into the security infrastructure. Instead of allocating the
> blobs from within the modules the modules tell the infrastructure how
> much space is required, and the space is allocated there.  There are
> no existing modules that require a key_free hook, so the call to it and
> the definition for it have been removed.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>

looks good

Reviewed-by: John Johansen <john.johansen@canonical.com>

> ---
>   include/linux/lsm_hook_defs.h     |  1 -
>   include/linux/lsm_hooks.h         |  1 +
>   security/security.c               | 39 +++++++++++++++++++++++++++++--
>   security/selinux/hooks.c          | 21 ++++-------------
>   security/selinux/include/objsec.h |  7 ++++++
>   security/smack/smack.h            |  7 ++++++
>   security/smack/smack_lsm.c        | 31 +++++++++++-------------
>   7 files changed, 69 insertions(+), 38 deletions(-)
> 
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 44488b1ab9a9..cc81f7f7c024 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -402,7 +402,6 @@ LSM_HOOK(int, 0, xfrm_decode_session, struct sk_buff *skb, u32 *secid,
>   #ifdef CONFIG_KEYS
>   LSM_HOOK(int, 0, key_alloc, struct key *key, const struct cred *cred,
>   	 unsigned long flags)
> -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)
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index efd4a0655159..7233bc0737be 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -76,6 +76,7 @@ struct lsm_blob_sizes {
>   	int	lbs_sock;
>   	int	lbs_superblock;
>   	int	lbs_ipc;
> +	int	lbs_key;
>   	int	lbs_msg_msg;
>   	int	lbs_task;
>   	int	lbs_xattr_count; /* number of xattr slots in new_xattrs array */
> diff --git a/security/security.c b/security/security.c
> index 5e93a72bdca6..92068ebd7e2b 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -227,6 +227,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
>   		blob_sizes.lbs_inode = sizeof(struct rcu_head);
>   	lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode);
>   	lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);
> +	lsm_set_blob_size(&needed->lbs_key, &blob_sizes.lbs_key);
>   	lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
>   	lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
>   	lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
> @@ -402,6 +403,9 @@ static void __init ordered_lsm_init(void)
>   	init_debug("file blob size       = %d\n", blob_sizes.lbs_file);
>   	init_debug("inode blob size      = %d\n", blob_sizes.lbs_inode);
>   	init_debug("ipc blob size        = %d\n", blob_sizes.lbs_ipc);
> +#ifdef CONFIG_KEYS
> +	init_debug("key blob size        = %d\n", blob_sizes.lbs_key);
> +#endif /* CONFIG_KEYS */
>   	init_debug("msg_msg blob size    = %d\n", blob_sizes.lbs_msg_msg);
>   	init_debug("sock blob size       = %d\n", blob_sizes.lbs_sock);
>   	init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
> @@ -718,6 +722,29 @@ static int lsm_ipc_alloc(struct kern_ipc_perm *kip)
>   	return 0;
>   }
>   
> +#ifdef CONFIG_KEYS
> +/**
> + * lsm_key_alloc - allocate a composite key blob
> + * @key: the key that needs a blob
> + *
> + * Allocate the key blob for all the modules
> + *
> + * Returns 0, or -ENOMEM if memory can't be allocated.
> + */
> +static int lsm_key_alloc(struct key *key)
> +{
> +	if (blob_sizes.lbs_key == 0) {
> +		key->security = NULL;
> +		return 0;
> +	}
> +
> +	key->security = kzalloc(blob_sizes.lbs_key, GFP_KERNEL);
> +	if (key->security == NULL)
> +		return -ENOMEM;
> +	return 0;
> +}
> +#endif /* CONFIG_KEYS */
> +
>   /**
>    * lsm_msg_msg_alloc - allocate a composite msg_msg blob
>    * @mp: the msg_msg that needs a blob
> @@ -5290,7 +5317,14 @@ EXPORT_SYMBOL(security_skb_classify_flow);
>   int security_key_alloc(struct key *key, const struct cred *cred,
>   		       unsigned long flags)
>   {
> -	return call_int_hook(key_alloc, key, cred, flags);
> +	int rc = lsm_key_alloc(key);
> +
> +	if (unlikely(rc))
> +		return rc;
> +	rc = call_int_hook(key_alloc, key, cred, flags);
> +	if (unlikely(rc))
> +		security_key_free(key);
> +	return rc;
>   }
>   
>   /**
> @@ -5301,7 +5335,8 @@ int security_key_alloc(struct key *key, const struct cred *cred,
>    */
>   void security_key_free(struct key *key)
>   {
> -	call_void_hook(key_free, key);
> +	kfree(key->security);
> +	key->security = NULL;
>   }
>   
>   /**
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 19346e1817ff..986825ba1cc5 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6658,11 +6658,7 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred,
>   			     unsigned long flags)
>   {
>   	const struct task_security_struct *tsec;
> -	struct key_security_struct *ksec;
> -
> -	ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL);
> -	if (!ksec)
> -		return -ENOMEM;
> +	struct key_security_struct *ksec = selinux_key(k);
>   
>   	tsec = selinux_cred(cred);
>   	if (tsec->keycreate_sid)
> @@ -6670,18 +6666,9 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred,
>   	else
>   		ksec->sid = tsec->sid;
>   
> -	k->security = ksec;
>   	return 0;
>   }
>   
> -static void selinux_key_free(struct key *k)
> -{
> -	struct key_security_struct *ksec = k->security;
> -
> -	k->security = NULL;
> -	kfree(ksec);
> -}
> -
>   static int selinux_key_permission(key_ref_t key_ref,
>   				  const struct cred *cred,
>   				  enum key_need_perm need_perm)
> @@ -6722,14 +6709,14 @@ static int selinux_key_permission(key_ref_t key_ref,
>   
>   	sid = cred_sid(cred);
>   	key = key_ref_to_ptr(key_ref);
> -	ksec = key->security;
> +	ksec = selinux_key(key);
>   
>   	return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL);
>   }
>   
>   static int selinux_key_getsecurity(struct key *key, char **_buffer)
>   {
> -	struct key_security_struct *ksec = key->security;
> +	struct key_security_struct *ksec = selinux_key(key);
>   	char *context = NULL;
>   	unsigned len;
>   	int rc;
> @@ -6981,6 +6968,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
>   	.lbs_file = sizeof(struct file_security_struct),
>   	.lbs_inode = sizeof(struct inode_security_struct),
>   	.lbs_ipc = sizeof(struct ipc_security_struct),
> +	.lbs_key = sizeof(struct key_security_struct),
>   	.lbs_msg_msg = sizeof(struct msg_security_struct),
>   	.lbs_sock = sizeof(struct sk_security_struct),
>   	.lbs_superblock = sizeof(struct superblock_security_struct),
> @@ -7318,7 +7306,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
>   #endif
>   
>   #ifdef CONFIG_KEYS
> -	LSM_HOOK_INIT(key_free, selinux_key_free),
>   	LSM_HOOK_INIT(key_permission, selinux_key_permission),
>   	LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity),
>   #ifdef CONFIG_KEY_NOTIFICATIONS
> diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
> index b074099acbaf..83b9443d6919 100644
> --- a/security/selinux/include/objsec.h
> +++ b/security/selinux/include/objsec.h
> @@ -195,6 +195,13 @@ selinux_superblock(const struct super_block *superblock)
>   	return superblock->s_security + selinux_blob_sizes.lbs_superblock;
>   }
>   
> +#ifdef CONFIG_KEYS
> +static inline struct key_security_struct *selinux_key(const struct key *key)
> +{
> +	return key->security + selinux_blob_sizes.lbs_key;
> +}
> +#endif /* CONFIG_KEYS */
> +
>   static inline struct sk_security_struct *selinux_sock(const struct sock *sock)
>   {
>   	return sock->sk_security + selinux_blob_sizes.lbs_sock;
> diff --git a/security/smack/smack.h b/security/smack/smack.h
> index 297f21446f45..dbf8d7226eb5 100644
> --- a/security/smack/smack.h
> +++ b/security/smack/smack.h
> @@ -360,6 +360,13 @@ static inline struct socket_smack *smack_sock(const struct sock *sock)
>   	return sock->sk_security + smack_blob_sizes.lbs_sock;
>   }
>   
> +#ifdef CONFIG_KEYS
> +static inline struct smack_known **smack_key(const struct key *key)
> +{
> +	return key->security + smack_blob_sizes.lbs_key;
> +}
> +#endif /* CONFIG_KEYS */
> +
>   /*
>    * Is the directory transmuting?
>    */
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index a931b44bc959..c57eacf1d3b1 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -4473,23 +4473,13 @@ static void smack_inet_csk_clone(struct sock *sk,
>   static int smack_key_alloc(struct key *key, const struct cred *cred,
>   			   unsigned long flags)
>   {
> +	struct smack_known **blob = smack_key(key);
>   	struct smack_known *skp = smk_of_task(smack_cred(cred));
>   
> -	key->security = skp;
> +	*blob = skp;
>   	return 0;
>   }
>   
> -/**
> - * smack_key_free - Clear the key security blob
> - * @key: the object
> - *
> - * Clear the blob pointer
> - */
> -static void smack_key_free(struct key *key)
> -{
> -	key->security = NULL;
> -}
> -
>   /**
>    * smack_key_permission - Smack access on a key
>    * @key_ref: gets to the object
> @@ -4503,6 +4493,8 @@ static int smack_key_permission(key_ref_t key_ref,
>   				const struct cred *cred,
>   				enum key_need_perm need_perm)
>   {
> +	struct smack_known **blob;
> +	struct smack_known *skp;
>   	struct key *keyp;
>   	struct smk_audit_info ad;
>   	struct smack_known *tkp = smk_of_task(smack_cred(cred));
> @@ -4540,7 +4532,9 @@ static int smack_key_permission(key_ref_t key_ref,
>   	 * If the key hasn't been initialized give it access so that
>   	 * it may do so.
>   	 */
> -	if (keyp->security == NULL)
> +	blob = smack_key(keyp);
> +	skp = *blob;
> +	if (skp == NULL)
>   		return 0;
>   	/*
>   	 * This should not occur
> @@ -4556,8 +4550,8 @@ static int smack_key_permission(key_ref_t key_ref,
>   	ad.a.u.key_struct.key = keyp->serial;
>   	ad.a.u.key_struct.key_desc = keyp->description;
>   #endif
> -	rc = smk_access(tkp, keyp->security, request, &ad);
> -	rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
> +	rc = smk_access(tkp, skp, request, &ad);
> +	rc = smk_bu_note("key access", tkp, skp, request, rc);
>   	return rc;
>   }
>   
> @@ -4572,11 +4566,12 @@ static int smack_key_permission(key_ref_t key_ref,
>    */
>   static int smack_key_getsecurity(struct key *key, char **_buffer)
>   {
> -	struct smack_known *skp = key->security;
> +	struct smack_known **blob = smack_key(key);
> +	struct smack_known *skp = *blob;
>   	size_t length;
>   	char *copy;
>   
> -	if (key->security == NULL) {
> +	if (skp == NULL) {
>   		*_buffer = NULL;
>   		return 0;
>   	}
> @@ -5010,6 +5005,7 @@ struct lsm_blob_sizes smack_blob_sizes __ro_after_init = {
>   	.lbs_file = sizeof(struct smack_known *),
>   	.lbs_inode = sizeof(struct inode_smack),
>   	.lbs_ipc = sizeof(struct smack_known *),
> +	.lbs_key = sizeof(struct smack_known *),
>   	.lbs_msg_msg = sizeof(struct smack_known *),
>   	.lbs_sock = sizeof(struct socket_smack),
>   	.lbs_superblock = sizeof(struct superblock_smack),
> @@ -5146,7 +5142,6 @@ static struct security_hook_list smack_hooks[] __ro_after_init = {
>    /* key management security hooks */
>   #ifdef CONFIG_KEYS
>   	LSM_HOOK_INIT(key_alloc, smack_key_alloc),
> -	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


  reply	other threads:[~2024-07-10 22:46 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20240710213230.11978-1-casey.ref@schaufler-ca.com>
2024-07-10 21:32 ` [PATCH v2 0/6] LSM: Infrastructure blob allocation Casey Schaufler
2024-07-10 21:32   ` [PATCH v2 1/6] LSM: Infrastructure management of the sock security Casey Schaufler
2024-07-10 21:32   ` [PATCH v2 2/6] LSM: Infrastructure management of the key security blob Casey Schaufler
2024-07-10 22:45     ` John Johansen [this message]
2024-07-10 21:32   ` [PATCH v2 3/6] LSM: Add helper for blob allocations Casey Schaufler
2024-07-10 21:32   ` [PATCH v2 4/6] LSM: Infrastructure management of the dev_tun blob Casey Schaufler
2024-07-10 23:08     ` John Johansen
2024-07-10 21:32   ` [PATCH v2 5/6] LSM: Infrastructure management of the infiniband blob Casey Schaufler
2024-07-10 23:09     ` John Johansen
2024-07-10 21:32   ` [PATCH v2 6/6] LSM: Infrastructure management of the perf_event security blob Casey Schaufler
2024-07-10 23:10     ` John Johansen
2024-07-11 20:15   ` [PATCH v2 0/6] LSM: Infrastructure blob allocation Paul Moore
2024-07-29 21:20     ` Paul Moore

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8b0ae00d-6876-4f44-9e01-10d45550860a@canonical.com \
    --to=john.johansen@canonical.com \
    --cc=casey@schaufler-ca.com \
    --cc=jmorris@namei.org \
    --cc=keescook@chromium.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mic@digikod.net \
    --cc=paul@paul-moore.com \
    --cc=penguin-kernel@i-love.sakura.ne.jp \
    --cc=serge@hallyn.com \
    --cc=stephen.smalley.work@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox