Thread (28 messages) 28 messages, 3 authors, 2024-07-10

Re: [PATCH 4/6] LSM: Infrastructure management of the dev_tun blob

From: Casey Schaufler <casey@schaufler-ca.com>
Date: 2024-07-09 23:11:51

On 7/9/2024 4:01 PM, John Johansen wrote:
On 7/8/24 14:39, Casey Schaufler wrote:
quoted
Move management of the dev_tun 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>
one issue below, besides Paul's point the rest of it looks good
quoted
---
  include/linux/lsm_hook_defs.h     |  2 +-
  include/linux/lsm_hooks.h         |  1 +
  security/security.c               | 11 ++++++++++-
  security/selinux/hooks.c          | 22 ++++++----------------
  security/selinux/include/objsec.h |  6 ++++++
  5 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/include/linux/lsm_hook_defs.h
b/include/linux/lsm_hook_defs.h
index 44488b1ab9a9..601e3092a7ed 100644
--- a/include/linux/lsm_hook_defs.h
+++ b/include/linux/lsm_hook_defs.h
@@ -352,7 +352,7 @@ LSM_HOOK(void, LSM_RET_VOID,
secmark_refcount_inc, void)
  LSM_HOOK(void, LSM_RET_VOID, secmark_refcount_dec, void)
  LSM_HOOK(void, LSM_RET_VOID, req_classify_flow, const struct
request_sock *req,
       struct flowi_common *flic)
-LSM_HOOK(int, 0, tun_dev_alloc_security, void **security)
+LSM_HOOK(int, 0, tun_dev_alloc_security, void *security)
  LSM_HOOK(void, LSM_RET_VOID, tun_dev_free_security, void *security)
  LSM_HOOK(int, 0, tun_dev_create, void)
  LSM_HOOK(int, 0, tun_dev_attach_queue, void *security)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7233bc0737be..0ff14ff128c8 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -80,6 +80,7 @@ struct lsm_blob_sizes {
      int    lbs_msg_msg;
      int    lbs_task;
      int    lbs_xattr_count; /* number of xattr slots in new_xattrs
array */
+    int    lbs_tun_dev;
  };
    /**
diff --git a/security/security.c b/security/security.c
index 438ec6708eb3..2c9d075f5f92 100644
--- a/security/security.c
+++ b/security/security.c
@@ -234,6 +234,7 @@ static void __init lsm_set_blob_sizes(struct
lsm_blob_sizes *needed)
      lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
      lsm_set_blob_size(&needed->lbs_superblock,
&blob_sizes.lbs_superblock);
      lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
+    lsm_set_blob_size(&needed->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
      lsm_set_blob_size(&needed->lbs_xattr_count,
                &blob_sizes.lbs_xattr_count);
  }
@@ -412,6 +413,7 @@ static void __init ordered_lsm_init(void)
      init_debug("sock blob size       = %d\n", blob_sizes.lbs_sock);
      init_debug("superblock blob size = %d\n",
blob_sizes.lbs_superblock);
      init_debug("task blob size       = %d\n", blob_sizes.lbs_task);
+    init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
      init_debug("xattr slots          = %d\n",
blob_sizes.lbs_xattr_count);
        /*
@@ -4851,7 +4853,13 @@ EXPORT_SYMBOL(security_secmark_refcount_dec);
   */
  int security_tun_dev_alloc_security(void **security)
  {
-    return call_int_hook(tun_dev_alloc_security, security);
+    int rc;
+
+    rc = lsm_blob_alloc(security, blob_sizes.lbs_tun_dev, GFP_KERNEL);
+    if (rc)
+        return rc;
+
+    return call_int_hook(tun_dev_alloc_security, *security);
we either need to free the blob here or make a change to tun_net_init.

if security_tun_dev_alloc fails it is not calling the corresponding
security_tun_dev_free_security()
Yes indeed, I missed that one. Fix in v2.
quoted
  }
  EXPORT_SYMBOL(security_tun_dev_alloc_security);
  @@ -4864,6 +4872,7 @@ EXPORT_SYMBOL(security_tun_dev_alloc_security);
  void security_tun_dev_free_security(void *security)
  {
      call_void_hook(tun_dev_free_security, security);
+    kfree(security);
  }
  EXPORT_SYMBOL(security_tun_dev_free_security);
  diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b3de2e941ef7..7f1d8358922a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5573,24 +5573,14 @@ static void selinux_req_classify_flow(const
struct request_sock *req,
      flic->flowic_secid = req->secid;
  }
  -static int selinux_tun_dev_alloc_security(void **security)
+static int selinux_tun_dev_alloc_security(void *security)
  {
-    struct tun_security_struct *tunsec;
+    struct tun_security_struct *tunsec = selinux_tun_dev(security);
  -    tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
-    if (!tunsec)
-        return -ENOMEM;
      tunsec->sid = current_sid();
-
-    *security = tunsec;
      return 0;
  }
  -static void selinux_tun_dev_free_security(void *security)
-{
-    kfree(security);
-}
-
  static int selinux_tun_dev_create(void)
  {
      u32 sid = current_sid();
@@ -5608,7 +5598,7 @@ static int selinux_tun_dev_create(void)
    static int selinux_tun_dev_attach_queue(void *security)
  {
-    struct tun_security_struct *tunsec = security;
+    struct tun_security_struct *tunsec = selinux_tun_dev(security);
        return avc_has_perm(current_sid(), tunsec->sid,
SECCLASS_TUN_SOCKET,
                  TUN_SOCKET__ATTACH_QUEUE, NULL);
@@ -5616,7 +5606,7 @@ static int selinux_tun_dev_attach_queue(void
*security)
    static int selinux_tun_dev_attach(struct sock *sk, void *security)
  {
-    struct tun_security_struct *tunsec = security;
+    struct tun_security_struct *tunsec = selinux_tun_dev(security);
      struct sk_security_struct *sksec = selinux_sock(sk);
        /* we don't currently perform any NetLabel based labeling
here and it
@@ -5634,7 +5624,7 @@ static int selinux_tun_dev_attach(struct sock
*sk, void *security)
    static int selinux_tun_dev_open(void *security)
  {
-    struct tun_security_struct *tunsec = security;
+    struct tun_security_struct *tunsec = selinux_tun_dev(security);
      u32 sid = current_sid();
      int err;
  @@ -6975,6 +6965,7 @@ struct lsm_blob_sizes selinux_blob_sizes
__ro_after_init = {
      .lbs_sock = sizeof(struct sk_security_struct),
      .lbs_superblock = sizeof(struct superblock_security_struct),
      .lbs_xattr_count = SELINUX_INODE_INIT_XATTRS,
+    .lbs_tun_dev = sizeof(struct tun_security_struct),
  };
    #ifdef CONFIG_PERF_EVENTS
@@ -7285,7 +7276,6 @@ static struct security_hook_list
selinux_hooks[] __ro_after_init = {
      LSM_HOOK_INIT(secmark_refcount_inc, selinux_secmark_refcount_inc),
      LSM_HOOK_INIT(secmark_refcount_dec, selinux_secmark_refcount_dec),
      LSM_HOOK_INIT(req_classify_flow, selinux_req_classify_flow),
-    LSM_HOOK_INIT(tun_dev_free_security,
selinux_tun_dev_free_security),
      LSM_HOOK_INIT(tun_dev_create, selinux_tun_dev_create),
      LSM_HOOK_INIT(tun_dev_attach_queue, selinux_tun_dev_attach_queue),
      LSM_HOOK_INIT(tun_dev_attach, selinux_tun_dev_attach),
diff --git a/security/selinux/include/objsec.h
b/security/selinux/include/objsec.h
index 83b9443d6919..461c6985977d 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -207,4 +207,10 @@ static inline struct sk_security_struct
*selinux_sock(const struct sock *sock)
      return sock->sk_security + selinux_blob_sizes.lbs_sock;
  }
  +static inline struct tun_security_struct *
+selinux_tun_dev(void *security)
+{
+    return security + selinux_blob_sizes.lbs_tun_dev;
+}
+
  #endif /* _SELINUX_OBJSEC_H_ */
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help