diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index dda1a9563..998cb4b20 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,10 @@ +2015-04-21 Corinna Vinschen + + * sec_acl.cc (get_posix_access): Check for Cygwin "standard" ACL. + Apply umask, if so. Align comments. + * security.cc (set_created_file_access): Fix permission masking by + incoming requested file mode. + 2015-04-20 Corinna Vinschen * sec_acl.cc (set_posix_access): Apply mask only in terms of execute bit diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc index bddd21c54..7d97fca02 100644 --- a/winsup/cygwin/sec_acl.cc +++ b/winsup/cygwin/sec_acl.cc @@ -549,6 +549,7 @@ get_posix_access (PSECURITY_DESCRIPTOR psd, bool owner_eq_group; bool just_created = false; + bool standard_ACEs_only = true; bool new_style = false; bool saw_user_obj = false; bool saw_group_obj = false; @@ -802,6 +803,17 @@ get_posix_access (PSECURITY_DESCRIPTOR psd, class_perm |= lacl[pos].a_perm; } } + /* For a newly created file, we'd like to know if we're running + with a standard ACL, one only consisting of POSIX perms, plus + SYSTEM and Admins as maximum non-POSIX perms entries. If it's + a standard ACL, we apply umask. That's not entirely correct, + but it's probably the best we can do. */ + else if (type & (USER | GROUP) + && just_created + && standard_ACEs_only + && ace_sid != well_known_system_sid + && ace_sid != well_known_admins_sid) + standard_ACEs_only = false; } } if ((ace->Header.AceFlags & SUB_CONTAINERS_AND_OBJECTS_INHERIT)) @@ -884,19 +896,19 @@ get_posix_access (PSECURITY_DESCRIPTOR psd, lacl[pos].a_id = ILLEGAL_GID; lacl[pos].a_perm = lacl[1].a_perm; /* == group perms */ } - /* If this is a just created file, and there are no default permissions - (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. - See POSIX 1003.1e draft 17. */ + /* 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 (!saw_user_obj) + if (standard_ACEs_only || !saw_user_obj) lacl[0].a_perm = (perms >> 6) & S_IRWXO; - if (!saw_group_obj) + if (standard_ACEs_only || !saw_group_obj) lacl[1].a_perm = (perms >> 3) & S_IRWXO; - if (!saw_other_obj) + if (standard_ACEs_only || !saw_other_obj) lacl[2].a_perm = perms & S_IRWXO; } /* Ensure that the default acl contains at least diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 6d891c1ac..5fca6746e 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -468,22 +468,34 @@ set_created_file_access (HANDLE handle, path_conv &pc, mode_t attr) if ((nentries = get_posix_access (sd, &attr_rd, &uid, &gid, aclp, MAX_ACL_ENTRIES)) >= 0) { - /* Symlinks always get the request POSIX perms. */ if (S_ISLNK (attr)) - attr_rd = 0777; - /* Overwrite ACL permissions as required by POSIX 1003.1e - draft 17. */ - aclp[0].a_perm = ((attr & attr_rd) >> 6) & S_IRWXO; - /* Deliberate deviation from POSIX 1003.1e here. We're not - writing CLASS_OBJ *or* GROUP_OBJ, but both. Otherwise we're - going to be in constant trouble with user expectations. */ - if ((idx = searchace (aclp, nentries, GROUP_OBJ)) >= 0) - aclp[idx].a_perm = ((attr & attr_rd) >> 3) & S_IRWXO; - if (nentries > MIN_ACL_ENTRIES - && (idx = searchace (aclp, nentries, CLASS_OBJ)) >= 0) - aclp[idx].a_perm = ((attr & attr_rd) >> 3) & S_IRWXO; - if ((idx = searchace (aclp, nentries, OTHER_OBJ)) >= 0) - aclp[idx].a_perm = (attr & attr_rd) & S_IRWXO; + { + /* Symlinks always get the request POSIX perms. */ + aclp[0].a_perm = (attr >> 6) & S_IRWXO; + if ((idx = searchace (aclp, nentries, GROUP_OBJ)) >= 0) + aclp[idx].a_perm = (attr >> 3) & S_IRWXO; + if (nentries > MIN_ACL_ENTRIES + && (idx = searchace (aclp, nentries, CLASS_OBJ)) >= 0) + aclp[idx].a_perm = (attr >> 3) & S_IRWXO; + if ((idx = searchace (aclp, nentries, OTHER_OBJ)) >= 0) + aclp[idx].a_perm = attr & S_IRWXO; + } + else + { + /* Overwrite ACL permissions as required by POSIX 1003.1e + draft 17. */ + aclp[0].a_perm &= (attr >> 6) & S_IRWXO; + /* Deliberate deviation from POSIX 1003.1e here. We're not + writing CLASS_OBJ *or* GROUP_OBJ, but both. Otherwise we're + going to be in constant trouble with user expectations. */ + if ((idx = searchace (aclp, nentries, GROUP_OBJ)) >= 0) + aclp[idx].a_perm &= (attr >> 3) & S_IRWXO; + if (nentries > MIN_ACL_ENTRIES + && (idx = searchace (aclp, nentries, CLASS_OBJ)) >= 0) + aclp[idx].a_perm &= (attr >> 3) & S_IRWXO; + if ((idx = searchace (aclp, nentries, OTHER_OBJ)) >= 0) + aclp[idx].a_perm &= attr & S_IRWXO; + } /* Construct appropriate inherit attribute for new directories. Basically we do this only for the sake of non-Cygwin applications. Cygwin applications don't need these. Additionally, if the