https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=0e6d36766c8358b27ba9c655a88647b41adc2914

commit 0e6d36766c8358b27ba9c655a88647b41adc2914
Author:     Corinna Vinschen <[email protected]>
AuthorDate: Wed Jan 15 12:26:06 2025 +0100
Commit:     Corinna Vinschen <[email protected]>
CommitDate: Wed Jan 15 12:27:03 2025 +0100

    Cygwin: get_posix_access: move umask masking to the end
    
    umask handling for new file gets overriden by subsequent merging of
    permissions in Windows-generated ACLs.  Fix this by performing
    umask masking after all other ACL manipulations.
    
    Fixes: a8716448cecc ("Simplify "Windows-standard-like" permissions")
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 winsup/cygwin/sec/acl.cc | 190 +++++++++++++++++++++++------------------------
 1 file changed, 95 insertions(+), 95 deletions(-)

diff --git a/winsup/cygwin/sec/acl.cc b/winsup/cygwin/sec/acl.cc
index aab567804933..9e041acc1203 100644
--- a/winsup/cygwin/sec/acl.cc
+++ b/winsup/cygwin/sec/acl.cc
@@ -1016,101 +1016,6 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
            }
        }
     }
-  /* If this is a just created file, and this is an ACL with only standard
-     entries, or if standard POSIX permissions are missing (probably no
-     inherited ACEs so created from a default DACL), assign the permissions
-     specified by the file creation mask.  The values get masked by the
-     actually requested permissions by the caller per POSIX 1003.1e draft 17. 
*/
-  if (just_created)
-    {
-      mode_t perms = (S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask;
-      if (standard_ACEs_only || !saw_user_obj)
-       lacl[0].a_perm = (perms >> 6) & S_IRWXO;
-      if (standard_ACEs_only || !saw_group_obj)
-       lacl[1].a_perm = (perms >> 3) & S_IRWXO;
-      if (standard_ACEs_only || !saw_other_obj)
-       lacl[2].a_perm = perms & S_IRWXO;
-    }
-  /* If this is an old-style or non-Cygwin ACL, and secondary user and group
-     entries exist in the ACL, fake a matching CLASS_OBJ entry. The CLASS_OBJ
-     permissions are the or'ed permissions of the primary group permissions
-     and all secondary user and group permissions. */
-  if (!new_style && has_class_perm
-      && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
-    {
-      lacl[pos].a_type = CLASS_OBJ;
-      lacl[pos].a_id = ACL_UNDEFINED_ID;
-      class_perm |= lacl[1].a_perm;
-      lacl[pos].a_perm = class_perm;
-      aclsid[pos] = well_known_null_sid;
-    }
-  /* For ptys, fake a mask if the admins group is neither owner nor group.
-     In that case we have an extra ACE for the admins group, and we need a
-     CLASS_OBJ to get a valid POSIX ACL.  However, Windows filters the ACE
-     Mask value so it only reflects the bit values supported by the object
-     type.  The result is that we can't set an explicit CLASS_OBJ value for
-     ptys in the NULL SID ACE. */
-  else if (S_ISCHR (attr) && owner_sid != well_known_admins_sid
-          && group_sid != well_known_admins_sid
-          && (pos = searchace (lacl, MAX_ACL_ENTRIES, CLASS_OBJ)) >= 0)
-    {
-      lacl[pos].a_type = CLASS_OBJ;
-      lacl[pos].a_id = ACL_UNDEFINED_ID;
-      lacl[pos].a_perm = lacl[1].a_perm; /* == group perms */
-      aclsid[pos] = well_known_null_sid;
-    }
-  /* Ensure that the default acl contains at least
-     DEF_(USER|GROUP|OTHER)_OBJ entries.  */
-  if (types_def && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
-    {
-      if (!(types_def & USER_OBJ))
-       {
-         lacl[pos].a_type = DEF_USER_OBJ;
-         lacl[pos].a_id = ACL_UNDEFINED_ID;
-         lacl[pos].a_perm = lacl[0].a_perm;
-         aclsid[pos] = well_known_creator_owner_sid;
-         pos++;
-       }
-      if (!(types_def & GROUP_OBJ) && pos < MAX_ACL_ENTRIES)
-       {
-         lacl[pos].a_type = DEF_GROUP_OBJ;
-         lacl[pos].a_id = ACL_UNDEFINED_ID;
-         lacl[pos].a_perm = lacl[1].a_perm;
-         /* If owner == group, the owner perms should be used. */
-         if (owner_eq_group)
-           lacl[pos].a_perm |= lacl[0].a_perm;
-         /* Note the position of the DEF_GROUP_OBJ entry. */
-         def_pgrp_pos = pos;
-         aclsid[pos] = well_known_creator_group_sid;
-         pos++;
-       }
-      if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES)
-       {
-         lacl[pos].a_type = DEF_OTHER_OBJ;
-         lacl[pos].a_id = ACL_UNDEFINED_ID;
-         lacl[pos].a_perm = lacl[2].a_perm;
-         aclsid[pos] = well_known_world_sid;
-       }
-    }
-  /* If this is an old-style or non-Cygwin ACL, and secondary user default
-     and group default entries exist in the ACL, fake a matching DEF_CLASS_OBJ
-     entry. The DEF_CLASS_OBJ permissions are the or'ed permissions of the
-     primary group default permissions and all secondary user and group def.
-     permissions. */
-  if (!new_style && has_def_class_perm
-      && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
-    {
-      lacl[pos].a_type = DEF_CLASS_OBJ;
-      lacl[pos].a_id = ACL_UNDEFINED_ID;
-      lacl[pos].a_perm = def_class_perm;
-      if (def_pgrp_pos >= 0)
-       lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm;
-      aclsid[pos] = well_known_null_sid;
-    }
-
-  /* Make sure `pos' contains the number of used entries in lacl. */
-  if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)
-    pos = MAX_ACL_ENTRIES;
 
   /* For old-style or non-Cygwin ACLs, check for merging permissions. */
   if (!new_style)
@@ -1199,11 +1104,106 @@ get_posix_access (PSECURITY_DESCRIPTOR psd,
              lacl[idx].a_perm |= lacl[obj_idx].a_perm;
        }
     }
+  /* If this is an old-style or non-Cygwin ACL, and secondary user and group
+     entries exist in the ACL, fake a matching CLASS_OBJ entry. The CLASS_OBJ
+     permissions are the or'ed permissions of the primary group permissions
+     and all secondary user and group permissions. */
+  if (!new_style && has_class_perm
+      && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
+    {
+      lacl[pos].a_type = CLASS_OBJ;
+      lacl[pos].a_id = ACL_UNDEFINED_ID;
+      class_perm |= lacl[1].a_perm;
+      lacl[pos].a_perm = class_perm;
+      aclsid[pos] = well_known_null_sid;
+    }
+  /* For ptys, fake a mask if the admins group is neither owner nor group.
+     In that case we have an extra ACE for the admins group, and we need a
+     CLASS_OBJ to get a valid POSIX ACL.  However, Windows filters the ACE
+     Mask value so it only reflects the bit values supported by the object
+     type.  The result is that we can't set an explicit CLASS_OBJ value for
+     ptys in the NULL SID ACE. */
+  else if (S_ISCHR (attr) && owner_sid != well_known_admins_sid
+          && group_sid != well_known_admins_sid
+          && (pos = searchace (lacl, MAX_ACL_ENTRIES, CLASS_OBJ)) >= 0)
+    {
+      lacl[pos].a_type = CLASS_OBJ;
+      lacl[pos].a_id = ACL_UNDEFINED_ID;
+      lacl[pos].a_perm = lacl[1].a_perm; /* == group perms */
+      aclsid[pos] = well_known_null_sid;
+    }
+  /* Ensure that the default acl contains at least
+     DEF_(USER|GROUP|OTHER)_OBJ entries.  */
+  if (types_def && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
+    {
+      if (!(types_def & USER_OBJ))
+       {
+         lacl[pos].a_type = DEF_USER_OBJ;
+         lacl[pos].a_id = ACL_UNDEFINED_ID;
+         lacl[pos].a_perm = lacl[0].a_perm;
+         aclsid[pos] = well_known_creator_owner_sid;
+         pos++;
+       }
+      if (!(types_def & GROUP_OBJ) && pos < MAX_ACL_ENTRIES)
+       {
+         lacl[pos].a_type = DEF_GROUP_OBJ;
+         lacl[pos].a_id = ACL_UNDEFINED_ID;
+         lacl[pos].a_perm = lacl[1].a_perm;
+         /* If owner == group, the owner perms should be used. */
+         if (owner_eq_group)
+           lacl[pos].a_perm |= lacl[0].a_perm;
+         /* Note the position of the DEF_GROUP_OBJ entry. */
+         def_pgrp_pos = pos;
+         aclsid[pos] = well_known_creator_group_sid;
+         pos++;
+       }
+      if (!(types_def & OTHER_OBJ) && pos < MAX_ACL_ENTRIES)
+       {
+         lacl[pos].a_type = DEF_OTHER_OBJ;
+         lacl[pos].a_id = ACL_UNDEFINED_ID;
+         lacl[pos].a_perm = lacl[2].a_perm;
+         aclsid[pos] = well_known_world_sid;
+       }
+    }
+  /* If this is an old-style or non-Cygwin ACL, and secondary user default
+     and group default entries exist in the ACL, fake a matching DEF_CLASS_OBJ
+     entry. The DEF_CLASS_OBJ permissions are the or'ed permissions of the
+     primary group default permissions and all secondary user and group def.
+     permissions. */
+  if (!new_style && has_def_class_perm
+      && (pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) >= 0)
+    {
+      lacl[pos].a_type = DEF_CLASS_OBJ;
+      lacl[pos].a_id = ACL_UNDEFINED_ID;
+      lacl[pos].a_perm = def_class_perm;
+      if (def_pgrp_pos >= 0)
+       lacl[pos].a_perm |= lacl[def_pgrp_pos].a_perm;
+      aclsid[pos] = well_known_null_sid;
+    }
+
+  /* Make sure `pos' contains the number of used entries in lacl. */
+  if ((pos = searchace (lacl, MAX_ACL_ENTRIES, 0)) < 0)
+    pos = MAX_ACL_ENTRIES;
   /* If owner SID == group SID (Microsoft Accounts) merge group perms into
      user perms but leave group perms intact.  That's a fake, but it allows
      to keep track of the POSIX group perms without much effort. */
   if (owner_eq_group)
     lacl[0].a_perm |= lacl[1].a_perm;
+  /* If this is a just created file, and this is an ACL with only standard
+     entries, or if standard POSIX permissions are missing (probably no
+     inherited ACEs so created from a default DACL), assign the permissions
+     specified by the file creation mask.  The values get masked by the
+     actually requested permissions by the caller per POSIX 1003.1e draft 17. 
*/
+  if (just_created)
+    {
+      mode_t perms = (S_IRWXU | S_IRWXG | S_IRWXO) & ~cygheap->umask;
+      if (standard_ACEs_only || !saw_user_obj)
+       lacl[0].a_perm = (perms >> 6) & S_IRWXO;
+      if (standard_ACEs_only || !saw_group_obj)
+       lacl[1].a_perm = (perms >> 3) & S_IRWXO;
+      if (standard_ACEs_only || !saw_other_obj)
+       lacl[2].a_perm = perms & S_IRWXO;
+    }
   /* Construct POSIX permission bits.  Fortunately we know exactly where
      to fetch the affecting bits from, at least as long as the array
      hasn't been sorted. */

Reply via email to