@@ -2417,7 +2417,8 @@ static void fs__chmod(uv_fs_t* req) {
24172417    /* Skip this EA if it isn't an SID, or it is "Everyone" or our actual group */ 
24182418    if  (pOldEAs [ea_idx ].Trustee .TrusteeForm  !=  TRUSTEE_IS_SID  || 
24192419        EqualSid (pEASid , psidEveryone ) || 
2420-         EqualSid (pEASid , psidGroup )) {
2420+         EqualSid (pEASid , psidGroup ) || 
2421+         EqualSid (pEASid , psidOwner )) {
24212422      continue ;
24222423    }
24232424
@@ -2434,43 +2435,52 @@ static void fs__chmod(uv_fs_t* req) {
24342435  }
24352436
24362437  /* Create an ACE for each triplet (user, group, other) */ 
2437-   numNewEAs  =  8  +  3 * numOtherGroups ;
2438+   numNewEAs  =  7  +  3 * numOtherGroups ;
24382439  ea  =  (PEXPLICIT_ACCESS_W ) malloc (sizeof (EXPLICIT_ACCESS_W )* numNewEAs );
24392440  u_mode  =  ((req -> fs .info .mode  &  S_IRWXU ) >> 6 );
24402441  g_mode  =  ((req -> fs .info .mode  &  S_IRWXG ) >> 3 );
2441-   o_mode  =  ((req -> fs .info .mode  &  S_IRWXO ) >> 0 );
2442+ 
2443+   /* 
2444+    * Because we do not control the ordering of ACE entries within the ACL that 
2445+    * we're building, the `SetNamedSecurityInfoW()` function call below will 
2446+    * place all DENY entries first, and all `ALLOW` entries second.  This 
2447+    * makes it impossible to support e.g. 0o757 permissions, because in order 
2448+    * to support an "allow" for "other", then a "deny" for "group", we are 
2449+    * unable to have an "allow" before the "deny" for "group".  To address this, 
2450+    * we simply do not allow the "other" entity to have permissions that "group" 
2451+    * itself does not have. 
2452+    */ 
2453+   o_mode  =  ((req -> fs .info .mode  &  S_IRWXO ) >> 0 ) &  g_mode ;
24422454
24432455  /* We start by revoking previous permissions for trustees we care about */ 
24442456  build_access_struct (& ea [0 ], psidOwner ,    TRUSTEE_IS_USER ,  0 , REVOKE_ACCESS );
24452457  build_access_struct (& ea [1 ], psidGroup ,    TRUSTEE_IS_GROUP , 0 , REVOKE_ACCESS );
24462458  build_access_struct (& ea [2 ], psidEveryone , TRUSTEE_IS_GROUP , 0 , REVOKE_ACCESS );
24472459
24482460  /* 
2449-    * We also add explicit denies to user and group if the user shouldn't have 
2450-    * a permission but the group or everyone can, for instance. 
2461+    * We also add explicit denies to user if the group shouldn't have a permission. 
24512462   */ 
2452-   u_deny_mode  =  (~u_mode ) &  (g_mode  | o_mode );
2453-   g_deny_mode  =  (~g_mode ) &  o_mode ;
2463+   u_deny_mode  =  (~u_mode ) &  (g_mode );
24542464  build_access_struct (& ea [3 ], psidOwner , TRUSTEE_IS_USER ,  u_deny_mode , DENY_ACCESS );
2455-   build_access_struct (& ea [4 ], psidGroup , TRUSTEE_IS_GROUP , g_deny_mode , DENY_ACCESS );
24562465
24572466  /* Next, add explicit allows for (owner, group, other) */ 
2458-   build_access_struct (& ea [5 ], psidOwner ,    TRUSTEE_IS_USER ,  u_mode , SET_ACCESS );
2459-   build_access_struct (& ea [6 ], psidGroup ,    TRUSTEE_IS_GROUP , g_mode , SET_ACCESS );
2460-   build_access_struct (& ea [7 ], psidEveryone , TRUSTEE_IS_GROUP , o_mode , SET_ACCESS );
2467+   build_access_struct (& ea [4 ], psidOwner ,    TRUSTEE_IS_USER ,  u_mode , SET_ACCESS );
2468+   build_access_struct (& ea [5 ], psidGroup ,    TRUSTEE_IS_GROUP , g_mode , SET_ACCESS );
2469+   build_access_struct (& ea [6 ], psidEveryone , TRUSTEE_IS_GROUP , o_mode , SET_ACCESS );
24612470
24622471  /* 
24632472   * Iterate over all old ACEs, looking for groups that we belong to, and setting 
24642473   * the appropriate access bits for those groups (as g_mode) 
24652474   */ 
2466-   ea_write_idx  =  8 ;
2475+   ea_write_idx  =  7 ;
24672476  for  (ea_idx = 0 ; ea_idx < numOldEAs ; ++ ea_idx ) {
24682477    BOOL  isMember  =  FALSE;
24692478    PSID  pEASid  =  (PSID )pOldEAs [ea_idx ].Trustee .ptstrName ;
24702479    /* Skip this EA if it isn't an SID, or it is "Everyone" or our actual group */ 
24712480    if  (pOldEAs [ea_idx ].Trustee .TrusteeForm  !=  TRUSTEE_IS_SID  || 
24722481        EqualSid (pEASid , psidEveryone ) || 
2473-         EqualSid (pEASid , psidGroup )) {
2482+         EqualSid (pEASid , psidGroup ) || 
2483+         EqualSid (pEASid , psidOwner )) {
24742484      continue ;
24752485    }
24762486
0 commit comments