diff options
-rw-r--r-- | winsup/cygwin/ChangeLog | 11 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.cc | 20 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/security.cc | 17 | ||||
-rw-r--r-- | winsup/cygwin/security.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/spawn.cc | 5 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 4 |
7 files changed, 38 insertions, 25 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c62fe7ce9..f7cc25d6b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,14 @@ +2009-09-25 Eric Blake <ebb9@byu.net> + + * fhandler.h (fhandler_base::fhaccess): Add parameter. + * security.h (check_file_access, check_registry_access): Likewise. + * security.cc (check_file_access, check_registry_access) + (check_access): Implement new parameter. + * fhandler.cc (fhandler_base::fhaccess): Likewise. + (device_access_denied): Update caller. + * syscalls.cc (access, faccessat): Update callers. + * spawn.cc (find_exec, fixup): Likewise. + 2009-09-24 Corinna Vinschen <corinna@vinschen.de> * posix_ipc.cc (mq_open): Avoid closing the same descriptor twice in diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index b52d7c2f1..5f501a7b6 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -344,11 +344,11 @@ fhandler_base::device_access_denied (int flags) if (!mode) mode |= R_OK; - return fhaccess (mode); + return fhaccess (mode, true); } int -fhandler_base::fhaccess (int flags) +fhandler_base::fhaccess (int flags, bool effective) { int res = -1; if (error ()) @@ -373,12 +373,12 @@ fhandler_base::fhaccess (int flags) goto eaccess_done; else if (has_acls ()) { - res = check_file_access (pc, flags); + res = check_file_access (pc, flags, effective); goto done; } else if (get_device () == FH_REGISTRY && open (O_RDONLY, 0) && get_handle ()) { - res = check_registry_access (get_handle (), flags); + res = check_registry_access (get_handle (), flags, effective); close (); return res; } @@ -389,12 +389,12 @@ fhandler_base::fhaccess (int flags) if (flags & R_OK) { - if (st.st_uid == myself->uid) + if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid)) { if (!(st.st_mode & S_IRUSR)) goto eaccess_done; } - else if (st.st_gid == myself->gid) + else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid)) { if (!(st.st_mode & S_IRGRP)) goto eaccess_done; @@ -405,12 +405,12 @@ fhandler_base::fhaccess (int flags) if (flags & W_OK) { - if (st.st_uid == myself->uid) + if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid)) { if (!(st.st_mode & S_IWUSR)) goto eaccess_done; } - else if (st.st_gid == myself->gid) + else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid)) { if (!(st.st_mode & S_IWGRP)) goto eaccess_done; @@ -421,12 +421,12 @@ fhandler_base::fhaccess (int flags) if (flags & X_OK) { - if (st.st_uid == myself->uid) + if (st.st_uid == (effective ? myself->uid : cygheap->user.real_uid)) { if (!(st.st_mode & S_IXUSR)) goto eaccess_done; } - else if (st.st_gid == myself->gid) + else if (st.st_gid == (effective ? myself->gid : cygheap->user.real_gid)) { if (!(st.st_mode & S_IXGRP)) goto eaccess_done; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 1544cc60c..dd9b59184 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -392,7 +392,7 @@ class fhandler_base bool is_fs_special () {return pc.is_fs_special ();} bool issymlink () {return pc.issymlink ();} bool device_access_denied (int) __attribute__ ((regparm (2))); - int fhaccess (int flags) __attribute__ ((regparm (2))); + int fhaccess (int flags, bool) __attribute__ ((regparm (3))); }; class fhandler_mailslot : public fhandler_base diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc index 00a8c32cd..c33be76c7 100644 --- a/winsup/cygwin/security.cc +++ b/winsup/cygwin/security.cc @@ -1,7 +1,7 @@ /* security.cc: NT file access control functions Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007 Red Hat, Inc. + 2006, 2007, 2008, 2009 Red Hat, Inc. Originaly written by Gunther Ebert, gunther.ebert@ixos-leipzig.de Completely rewritten by Corinna Vinschen <corinna@vinschen.de> @@ -725,15 +725,16 @@ set_file_attribute (HANDLE handle, path_conv &pc, static int check_access (security_descriptor &sd, GENERIC_MAPPING &mapping, - DWORD desired, int flags) + DWORD desired, int flags, bool effective) { int ret = -1; BOOL status; DWORD granted; DWORD plen = sizeof (PRIVILEGE_SET) + 3 * sizeof (LUID_AND_ATTRIBUTES); PPRIVILEGE_SET pset = (PPRIVILEGE_SET) alloca (plen); - HANDLE tok = cygheap->user.issetuid () ? cygheap->user.imp_token () - : hProcImpToken; + HANDLE tok = ((effective && cygheap->user.issetuid ()) + ? cygheap->user.imp_token () + : hProcImpToken); if (!tok && !DuplicateTokenEx (hProcToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, @@ -794,7 +795,7 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping, } int -check_file_access (path_conv &pc, int flags) +check_file_access (path_conv &pc, int flags, bool effective) { security_descriptor sd; int ret = -1; @@ -810,13 +811,13 @@ check_file_access (path_conv &pc, int flags) if (flags & X_OK) desired |= FILE_EXECUTE; if (!get_file_sd (NULL, pc, sd)) - ret = check_access (sd, mapping, desired, flags); + ret = check_access (sd, mapping, desired, flags, effective); debug_printf ("flags %x, ret %d", flags, ret); return ret; } int -check_registry_access (HANDLE hdl, int flags) +check_registry_access (HANDLE hdl, int flags, bool effective) { security_descriptor sd; int ret = -1; @@ -832,7 +833,7 @@ check_registry_access (HANDLE hdl, int flags) if (flags & X_OK) desired |= KEY_QUERY_VALUE; if (!get_reg_sd (hdl, sd)) - ret = check_access (sd, mapping, desired, flags); + ret = check_access (sd, mapping, desired, flags, effective); /* As long as we can't write the registry... */ if (flags & W_OK) { diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h index 7b09bc0ad..781def9d5 100644 --- a/winsup/cygwin/security.h +++ b/winsup/cygwin/security.h @@ -350,8 +350,8 @@ LONG __stdcall set_file_sd (HANDLE fh, path_conv &, security_descriptor &sd, bool is_chown); bool __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); bool __stdcall add_access_denied_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit); -int __stdcall check_file_access (path_conv &, int); -int __stdcall check_registry_access (HANDLE, int); +int __stdcall check_file_access (path_conv &, int, bool); +int __stdcall check_registry_access (HANDLE, int, bool); void set_security_attribute (path_conv &pc, int attribute, PSECURITY_ATTRIBUTES psa, diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index c5b5bee9a..5c86c4b5c 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -169,7 +169,7 @@ find_exec (const char *name, path_conv& buf, const char *mywinenv, if ((suffix = perhaps_suffix (tmp, buf, err, opt)) != NULL) { - if (buf.has_acls () && check_file_access (buf, X_OK)) + if (buf.has_acls () && check_file_access (buf, X_OK, true)) continue; if (posix == tmp) @@ -1083,7 +1083,8 @@ just_shell: /* Check if script is executable. Otherwise we start non-executable scripts successfully, which is incorrect behaviour. */ - if (real_path.has_acls () && check_file_access (real_path, X_OK) < 0) + if (real_path.has_acls () + && check_file_access (real_path, X_OK, true) < 0) return -1; /* errno is already set. */ /* Replace argv[0] with the full path to the script if this is the diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 542a122d7..3eb77fd07 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1572,7 +1572,7 @@ access (const char *fn, int flags) fhandler_base *fh = build_fh_name (fn, NULL, PC_SYM_FOLLOW, stat_suffixes); if (fh) { - res = fh->fhaccess (flags); + res = fh->fhaccess (flags, false); delete fh; } } @@ -3862,7 +3862,7 @@ faccessat (int dirfd, const char *pathname, int mode, int flags) stat_suffixes); if (fh) { - res = fh->fhaccess (mode); + res = fh->fhaccess (mode, flags & AT_EACCESS); delete fh; } } |