lsm: infrastructure management of the infiniband blob
authorCasey Schaufler <casey@schaufler-ca.com>
Wed, 10 Jul 2024 21:32:29 +0000 (14:32 -0700)
committerPaul Moore <paul@paul-moore.com>
Mon, 29 Jul 2024 20:54:52 +0000 (16:54 -0400)
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.
There are no longer any modules that require the ib_free() hook.
The hook definition has been removed.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: John Johansen <john.johansen@canonical.com>
[PM: subject tweak, selinux style fixes]
Signed-off-by: Paul Moore <paul@paul-moore.com>
include/linux/lsm_hook_defs.h
include/linux/lsm_hooks.h
security/security.c
security/selinux/hooks.c
security/selinux/include/objsec.h

index 22c475f530aea58c4a737c6d9cc0179fe90d95c1..4fcbc5b3f58ce36c35e73ee752f6fd613d151657 100644 (file)
@@ -373,8 +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(void, LSM_RET_VOID, ib_free_security, void *sec)
+LSM_HOOK(int, 0, ib_alloc_security, void *sec)
 #endif /* CONFIG_SECURITY_INFINIBAND */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
index 0ff14ff128c800f211bb83436e0fd72e455ef2ec..b6fc6ac887238dd069e64106e9e63b18d36758ea 100644 (file)
@@ -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;
index 137a1f7e0e8bf5fb1530da338cda636ba99ddd77..80dc58d60aabb3f77a55429309346d32889a67cc 100644 (file)
@@ -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.
@@ -402,6 +403,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
@@ -5096,7 +5098,18 @@ 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;
+
+       rc = call_int_hook(ib_alloc_security, *sec);
+       if (rc) {
+               kfree(*sec);
+               *sec = NULL;
+       }
+       return rc;
 }
 EXPORT_SYMBOL(security_ib_alloc_security);
 
@@ -5108,7 +5121,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 */
index 793cfdc4c0ef51e0c1fccf5acc4f5e49a1aa3343..675c69ebb77c3508ebcef329e9984e2b8ab88792 100644 (file)
@@ -6781,23 +6781,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
@@ -6969,6 +6959,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
@@ -7288,7 +7279,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),
index b7d4b1fc8feec4c979ec37b413d8682c200608c3..ed9e37f3c9b55126643b14100b3cf9fa0e4519ce 100644 (file)
@@ -212,4 +212,9 @@ static inline struct tun_security_struct *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_ */