]> Git Repo - J-linux.git/commitdiff
Merge tag 'selinux-pr-20240911' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Mon, 16 Sep 2024 14:55:42 +0000 (16:55 +0200)
committerLinus Torvalds <[email protected]>
Mon, 16 Sep 2024 14:55:42 +0000 (16:55 +0200)
Pull selinux updates from Paul Moore:

 - Ensure that both IPv4 and IPv6 connections are properly initialized

   While we always properly initialized IPv4 connections early in their
   life, we missed the necessary IPv6 change when we were adding IPv6
   support.

 - Annotate the SELinux inode revalidation function to quiet KCSAN

   KCSAN correctly identifies a race in __inode_security_revalidate()
   when we check to see if an inode's SELinux has been properly
   initialized. While KCSAN is correct, it is an intentional choice made
   for performance reasons; if necessary, we check the state a second
   time, this time with a lock held, before initializing the inode's
   state.

 - Code cleanups, simplification, etc.

   A handful of individual patches to simplify some SELinux kernel
   logic, improve return code granularity via ERR_PTR(), follow the
   guidance on using KMEM_CACHE(), and correct some minor style
   problems.

* tag 'selinux-pr-20240911' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: fix style problems in security/selinux/include/audit.h
  selinux: simplify avc_xperms_audit_required()
  selinux: mark both IPv4 and IPv6 accepted connection sockets as labeled
  selinux: replace kmem_cache_create() with KMEM_CACHE()
  selinux: annotate false positive data race to avoid KCSAN warnings
  selinux: refactor code to return ERR_PTR in selinux_netlbl_sock_genattr
  selinux: Streamline type determination in security_compute_sid

1  2 
security/selinux/avc.c
security/selinux/hooks.c

diff --combined security/selinux/avc.c
index b49c44869dc462720bc9110f4a3aa895edb06537,e0d1a9dfaceeaac23af2c28c07aa4c8fef82aeff..cc0b0af20296170be8f001ae539eb29eae04e871
@@@ -134,18 -134,10 +134,10 @@@ static inline u32 avc_hash(u32 ssid, u3
   */
  void __init avc_init(void)
  {
-       avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
-                                       0, SLAB_PANIC, NULL);
-       avc_xperms_cachep = kmem_cache_create("avc_xperms_node",
-                                       sizeof(struct avc_xperms_node),
-                                       0, SLAB_PANIC, NULL);
-       avc_xperms_decision_cachep = kmem_cache_create(
-                                       "avc_xperms_decision_node",
-                                       sizeof(struct avc_xperms_decision_node),
-                                       0, SLAB_PANIC, NULL);
-       avc_xperms_data_cachep = kmem_cache_create("avc_xperms_data",
-                                       sizeof(struct extended_perms_data),
-                                       0, SLAB_PANIC, NULL);
+       avc_node_cachep = KMEM_CACHE(avc_node, SLAB_PANIC);
+       avc_xperms_cachep = KMEM_CACHE(avc_xperms_node, SLAB_PANIC);
+       avc_xperms_decision_cachep = KMEM_CACHE(avc_xperms_decision_node, SLAB_PANIC);
+       avc_xperms_data_cachep = KMEM_CACHE(extended_perms_data, SLAB_PANIC);
  }
  
  int avc_get_hash_stats(char *page)
@@@ -330,12 -322,12 +322,12 @@@ static int avc_add_xperms_decision(stru
  {
        struct avc_xperms_decision_node *dest_xpd;
  
 -      node->ae.xp_node->xp.len++;
        dest_xpd = avc_xperms_decision_alloc(src->used);
        if (!dest_xpd)
                return -ENOMEM;
        avc_copy_xperms_decision(&dest_xpd->xpd, src);
        list_add(&dest_xpd->xpd_list, &node->ae.xp_node->xpd_head);
 +      node->ae.xp_node->xp.len++;
        return 0;
  }
  
@@@ -396,7 -388,7 +388,7 @@@ static inline u32 avc_xperms_audit_requ
                audited = denied & avd->auditdeny;
                if (audited && xpd) {
                        if (avc_xperms_has_perm(xpd, perm, XPERMS_DONTAUDIT))
-                               audited &= ~requested;
+                               audited = 0;
                }
        } else if (result) {
                audited = denied = requested;
                audited = requested & avd->auditallow;
                if (audited && xpd) {
                        if (!avc_xperms_has_perm(xpd, perm, XPERMS_AUDITALLOW))
-                               audited &= ~requested;
+                               audited = 0;
                }
        }
  
@@@ -907,11 -899,7 +899,11 @@@ static int avc_update_node(u32 event, u
                node->ae.avd.auditdeny &= ~perms;
                break;
        case AVC_CALLBACK_ADD_XPERMS:
 -              avc_add_xperms_decision(node, xpd);
 +              rc = avc_add_xperms_decision(node, xpd);
 +              if (rc) {
 +                      avc_node_kill(node);
 +                      goto out_unlock;
 +              }
                break;
        }
        avc_node_replace(node, orig);
diff --combined security/selinux/hooks.c
index cc123c6390a72f5467cc7eaafd5ac8677b10699b,70c335846336da7e236f79991efd9de93c496ce6..e9b630de2f79b1613365c0ab858a5099fea538c5
@@@ -282,8 -282,13 +282,13 @@@ static int __inode_security_revalidate(
  
        might_sleep_if(may_sleep);
  
+       /*
+        * The check of isec->initialized below is racy but
+        * inode_doinit_with_dentry() will recheck with
+        * isec->lock held.
+        */
        if (selinux_initialized() &&
-           isec->initialized != LABEL_INITIALIZED) {
+           data_race(isec->initialized != LABEL_INITIALIZED)) {
                if (!may_sleep)
                        return -ECHILD;
  
@@@ -3852,17 -3857,7 +3857,17 @@@ static int selinux_file_mprotect(struc
        if (default_noexec &&
            (prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
                int rc = 0;
 -              if (vma_is_initial_heap(vma)) {
 +              /*
 +               * We don't use the vma_is_initial_heap() helper as it has
 +               * a history of problems and is currently broken on systems
 +               * where there is no heap, e.g. brk == start_brk.  Before
 +               * replacing the conditional below with vma_is_initial_heap(),
 +               * or something similar, please ensure that the logic is the
 +               * same as what we have below or you have tested every possible
 +               * corner case you can think to test.
 +               */
 +              if (vma->vm_start >= vma->vm_mm->start_brk &&
 +                  vma->vm_end <= vma->vm_mm->brk) {
                        rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
                                          PROCESS__EXECHEAP, NULL);
                } else if (!vma->vm_file && (vma_is_initial_stack(vma) ||
@@@ -3950,7 -3945,7 +3955,7 @@@ static int selinux_file_send_sigiotask(
        struct file_security_struct *fsec;
  
        /* struct fown_struct is never outside the context of a struct file */
 -      file = container_of(fown, struct file, f_owner);
 +      file = fown->file;
  
        fsec = selinux_file(file);
  
@@@ -6660,8 -6655,8 +6665,8 @@@ static int selinux_inode_notifysecctx(s
   */
  static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
  {
 -      return __vfs_setxattr_noperm(&nop_mnt_idmap, dentry, XATTR_NAME_SELINUX,
 -                                   ctx, ctxlen, 0);
 +      return __vfs_setxattr_locked(&nop_mnt_idmap, dentry, XATTR_NAME_SELINUX,
 +                                   ctx, ctxlen, 0, NULL);
  }
  
  static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
This page took 0.071782 seconds and 4 git commands to generate.