diff mbox series

[5/6] LSM: Infrastructure management of the infiniband blob

Message ID 20240708213957.20519-6-casey@schaufler-ca.com (mailing list archive)
State Changes Requested
Delegated to: Paul Moore
Headers show
Series LSM: Infrastructure blob allocation | expand

Commit Message

Casey Schaufler July 8, 2024, 9:39 p.m. UTC
Move management of the infiniband security blob out of the individual
security modules and into the LSM infrastructure.  The security modules
tell the infrastructure how much space they require at initialization.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
 include/linux/lsm_hook_defs.h     |  2 +-
 include/linux/lsm_hooks.h         |  1 +
 security/security.c               | 11 ++++++++++-
 security/selinux/hooks.c          | 16 +++-------------
 security/selinux/include/objsec.h |  6 ++++++
 5 files changed, 21 insertions(+), 15 deletions(-)

Comments

Paul Moore July 9, 2024, 10:08 p.m. UTC | #1
On Jul  8, 2024 Casey Schaufler <casey@schaufler-ca.com> wrote:
> 
> Move management of the infiniband security blob out of the individual
> security modules and into the LSM infrastructure.  The security modules
> tell the infrastructure how much space they require at initialization.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
> ---
>  include/linux/lsm_hook_defs.h     |  2 +-
>  include/linux/lsm_hooks.h         |  1 +
>  security/security.c               | 11 ++++++++++-
>  security/selinux/hooks.c          | 16 +++-------------
>  security/selinux/include/objsec.h |  6 ++++++
>  5 files changed, 21 insertions(+), 15 deletions(-)

...

> diff --git a/security/security.c b/security/security.c
> index 2c9d075f5f92..731a54fabc79 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -5081,6 +5089,7 @@ EXPORT_SYMBOL(security_ib_alloc_security);
>  void security_ib_free_security(void *sec)
>  {
>  	call_void_hook(ib_free_security, sec);
> +	kfree(sec);
>  }
>  EXPORT_SYMBOL(security_ib_free_security);

Same comment as elsewhere, let's be consistent with the *free() hooks,
either we keep them or we remove them if unused (preferable).

--
paul-moore.com
John Johansen July 9, 2024, 11:38 p.m. UTC | #2
On 7/8/24 14:39, Casey Schaufler wrote:
> Move management of the infiniband security blob out of the individual
> security modules and into the LSM infrastructure.  The security modules
> tell the infrastructure how much space they require at initialization.
> 
> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>

an issue below, other than that and Paul's point it looks good

> ---
>   include/linux/lsm_hook_defs.h     |  2 +-
>   include/linux/lsm_hooks.h         |  1 +
>   security/security.c               | 11 ++++++++++-
>   security/selinux/hooks.c          | 16 +++-------------
>   security/selinux/include/objsec.h |  6 ++++++
>   5 files changed, 21 insertions(+), 15 deletions(-)
> 
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 601e3092a7ed..796ab400e992 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -373,7 +373,7 @@ LSM_HOOK(int, 0, mptcp_add_subflow, struct sock *sk, struct sock *ssk)
>   LSM_HOOK(int, 0, ib_pkey_access, void *sec, u64 subnet_prefix, u16 pkey)
>   LSM_HOOK(int, 0, ib_endport_manage_subnet, void *sec, const char *dev_name,
>   	 u8 port_num)
> -LSM_HOOK(int, 0, ib_alloc_security, void **sec)
> +LSM_HOOK(int, 0, ib_alloc_security, void *sec)
>   LSM_HOOK(void, LSM_RET_VOID, ib_free_security, void *sec)
>   #endif /* CONFIG_SECURITY_INFINIBAND */
>   
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 0ff14ff128c8..b6fc6ac88723 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -72,6 +72,7 @@ struct security_hook_list {
>   struct lsm_blob_sizes {
>   	int	lbs_cred;
>   	int	lbs_file;
> +	int	lbs_ib;
>   	int	lbs_inode;
>   	int	lbs_sock;
>   	int	lbs_superblock;
> diff --git a/security/security.c b/security/security.c
> index 2c9d075f5f92..731a54fabc79 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -219,6 +219,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
>   
>   	lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
>   	lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file);
> +	lsm_set_blob_size(&needed->lbs_ib, &blob_sizes.lbs_ib);
>   	/*
>   	 * The inode blob gets an rcu_head in addition to
>   	 * what the modules might need.
> @@ -404,6 +405,7 @@ static void __init ordered_lsm_init(void)
>   
>   	init_debug("cred blob size       = %d\n", blob_sizes.lbs_cred);
>   	init_debug("file blob size       = %d\n", blob_sizes.lbs_file);
> +	init_debug("ib blob size         = %d\n", blob_sizes.lbs_ib);
>   	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
> @@ -5068,7 +5070,13 @@ EXPORT_SYMBOL(security_ib_endport_manage_subnet);
>    */
>   int security_ib_alloc_security(void **sec)
>   {
> -	return call_int_hook(ib_alloc_security, sec);
> +	int rc;
> +
> +	rc = lsm_blob_alloc(sec, blob_sizes.lbs_ib, GFP_KERNEL);
> +	if (rc)
> +		return rc;
> +
> +	return call_int_hook(ib_alloc_security, *sec);

this has a similar problem to the tun dev. When security_ib_alloc() fails,
security_ib_free() hook isn't getting called

>   }
>   EXPORT_SYMBOL(security_ib_alloc_security);
>   
> @@ -5081,6 +5089,7 @@ EXPORT_SYMBOL(security_ib_alloc_security);
>   void security_ib_free_security(void *sec)
>   {
>   	call_void_hook(ib_free_security, sec);
> +	kfree(sec);
>   }
>   EXPORT_SYMBOL(security_ib_free_security);
>   #endif	/* CONFIG_SECURITY_INFINIBAND */
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 7f1d8358922a..79fe75603881 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -6776,23 +6776,13 @@ static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
>   			    INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
>   }
>   
> -static int selinux_ib_alloc_security(void **ib_sec)
> +static int selinux_ib_alloc_security(void *ib_sec)
>   {
> -	struct ib_security_struct *sec;
> +	struct ib_security_struct *sec = selinux_ib(ib_sec);
>   
> -	sec = kzalloc(sizeof(*sec), GFP_KERNEL);
> -	if (!sec)
> -		return -ENOMEM;
>   	sec->sid = current_sid();
> -
> -	*ib_sec = sec;
>   	return 0;
>   }
> -
> -static void selinux_ib_free_security(void *ib_sec)
> -{
> -	kfree(ib_sec);
> -}
>   #endif
>   
>   #ifdef CONFIG_BPF_SYSCALL
> @@ -6966,6 +6956,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
>   	.lbs_superblock = sizeof(struct superblock_security_struct),
>   	.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
>   	.lbs_tun_dev = sizeof(struct tun_security_struct),
> +	.lbs_ib = sizeof(struct ib_security_struct),
>   };
>   
>   #ifdef CONFIG_PERF_EVENTS
> @@ -7284,7 +7275,6 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
>   	LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
>   	LSM_HOOK_INIT(ib_endport_manage_subnet,
>   		      selinux_ib_endport_manage_subnet),
> -	LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
>   #endif
>   #ifdef CONFIG_SECURITY_NETWORK_XFRM
>   	LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
> diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
> index 461c6985977d..b1878f9395b5 100644
> --- a/security/selinux/include/objsec.h
> +++ b/security/selinux/include/objsec.h
> @@ -213,4 +213,10 @@ selinux_tun_dev(void *security)
>   	return security + selinux_blob_sizes.lbs_tun_dev;
>   }
>   
> +static inline struct ib_security_struct *
> +selinux_ib(void *ib_sec)
> +{
> +	return ib_sec + selinux_blob_sizes.lbs_ib;
> +}
> +
>   #endif /* _SELINUX_OBJSEC_H_ */
diff mbox series

Patch

diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
index 601e3092a7ed..796ab400e992 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -373,7 +373,7 @@  LSM_HOOK(int, 0, mptcp_add_subflow, struct sock *sk, struct sock *ssk)
 LSM_HOOK(int, 0, ib_pkey_access, void *sec, u64 subnet_prefix, u16 pkey)
 LSM_HOOK(int, 0, ib_endport_manage_subnet, void *sec, const char *dev_name,
 	 u8 port_num)
-LSM_HOOK(int, 0, ib_alloc_security, void **sec)
+LSM_HOOK(int, 0, ib_alloc_security, void *sec)
 LSM_HOOK(void, LSM_RET_VOID, ib_free_security, void *sec)
 #endif /* CONFIG_SECURITY_INFINIBAND */
 
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 0ff14ff128c8..b6fc6ac88723 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -72,6 +72,7 @@  struct security_hook_list {
 struct lsm_blob_sizes {
 	int	lbs_cred;
 	int	lbs_file;
+	int	lbs_ib;
 	int	lbs_inode;
 	int	lbs_sock;
 	int	lbs_superblock;
diff --git a/security/security.c b/security/security.c
index 2c9d075f5f92..731a54fabc79 100644
--- a/security/security.c
+++ b/security/security.c
@@ -219,6 +219,7 @@  static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
 
 	lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
 	lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file);
+	lsm_set_blob_size(&needed->lbs_ib, &blob_sizes.lbs_ib);
 	/*
 	 * The inode blob gets an rcu_head in addition to
 	 * what the modules might need.
@@ -404,6 +405,7 @@  static void __init ordered_lsm_init(void)
 
 	init_debug("cred blob size       = %d\n", blob_sizes.lbs_cred);
 	init_debug("file blob size       = %d\n", blob_sizes.lbs_file);
+	init_debug("ib blob size         = %d\n", blob_sizes.lbs_ib);
 	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
@@ -5068,7 +5070,13 @@  EXPORT_SYMBOL(security_ib_endport_manage_subnet);
  */
 int security_ib_alloc_security(void **sec)
 {
-	return call_int_hook(ib_alloc_security, sec);
+	int rc;
+
+	rc = lsm_blob_alloc(sec, blob_sizes.lbs_ib, GFP_KERNEL);
+	if (rc)
+		return rc;
+
+	return call_int_hook(ib_alloc_security, *sec);
 }
 EXPORT_SYMBOL(security_ib_alloc_security);
 
@@ -5081,6 +5089,7 @@  EXPORT_SYMBOL(security_ib_alloc_security);
 void security_ib_free_security(void *sec)
 {
 	call_void_hook(ib_free_security, sec);
+	kfree(sec);
 }
 EXPORT_SYMBOL(security_ib_free_security);
 #endif	/* CONFIG_SECURITY_INFINIBAND */
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7f1d8358922a..79fe75603881 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6776,23 +6776,13 @@  static int selinux_ib_endport_manage_subnet(void *ib_sec, const char *dev_name,
 			    INFINIBAND_ENDPORT__MANAGE_SUBNET, &ad);
 }
 
-static int selinux_ib_alloc_security(void **ib_sec)
+static int selinux_ib_alloc_security(void *ib_sec)
 {
-	struct ib_security_struct *sec;
+	struct ib_security_struct *sec = selinux_ib(ib_sec);
 
-	sec = kzalloc(sizeof(*sec), GFP_KERNEL);
-	if (!sec)
-		return -ENOMEM;
 	sec->sid = current_sid();
-
-	*ib_sec = sec;
 	return 0;
 }
-
-static void selinux_ib_free_security(void *ib_sec)
-{
-	kfree(ib_sec);
-}
 #endif
 
 #ifdef CONFIG_BPF_SYSCALL
@@ -6966,6 +6956,7 @@  struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
 	.lbs_superblock = sizeof(struct superblock_security_struct),
 	.lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
 	.lbs_tun_dev = sizeof(struct tun_security_struct),
+	.lbs_ib = sizeof(struct ib_security_struct),
 };
 
 #ifdef CONFIG_PERF_EVENTS
@@ -7284,7 +7275,6 @@  static struct security_hook_list selinux_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(ib_pkey_access, selinux_ib_pkey_access),
 	LSM_HOOK_INIT(ib_endport_manage_subnet,
 		      selinux_ib_endport_manage_subnet),
-	LSM_HOOK_INIT(ib_free_security, selinux_ib_free_security),
 #endif
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
 	LSM_HOOK_INIT(xfrm_policy_free_security, selinux_xfrm_policy_free),
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 461c6985977d..b1878f9395b5 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -213,4 +213,10 @@  selinux_tun_dev(void *security)
 	return security + selinux_blob_sizes.lbs_tun_dev;
 }
 
+static inline struct ib_security_struct *
+selinux_ib(void *ib_sec)
+{
+	return ib_sec + selinux_blob_sizes.lbs_ib;
+}
+
 #endif /* _SELINUX_OBJSEC_H_ */