https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=5f7ed4659b11e5dc37eb7bfe96a4d2941b0d0d67
commit 5f7ed4659b11e5dc37eb7bfe96a4d2941b0d0d67 Author: Corinna Vinschen <[email protected]> AuthorDate: Tue Jan 7 17:44:44 2025 +0100 Commit: Corinna Vinschen <[email protected]> CommitDate: Wed Jan 8 16:13:51 2025 +0100 Cygwin: access: Fix X_OK behaviour for backup operators and admins After commit a0933cd17d19, access(_, X_OK) returns 0 if the user holds SE_BACKUP_PRIVILEGE, even if the file's ACL denies execution to the user. This is triggered by trying to open the file with FILE_OPEN_FOR_BACKUP_INTENT. Fix check_file_access() so it checks for X_OK without specifying the FILE_OPEN_FOR_BACKUP_INTENT flag if the file is not a directory. Rearrange function slightly and add comments for easier comprehension. Fixes: a0933cd17d19 ("Cygwin: access: Correction for samba/SMB share") Reported-by: Bruno Haible <[email protected]> Co-authored-by: Takashi Yano <[email protected]> Signed-off-by: Corinna Vinschen <[email protected]> (cherry picked from commit 2e4db338ac125579d555aeee516e48588a628a16) Diff: --- winsup/cygwin/release/3.5.6 | 6 ++++++ winsup/cygwin/sec/base.cc | 27 ++++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/winsup/cygwin/release/3.5.6 b/winsup/cygwin/release/3.5.6 new file mode 100644 index 000000000000..45281ec34edb --- /dev/null +++ b/winsup/cygwin/release/3.5.6 @@ -0,0 +1,6 @@ +Fixes: +------ + +- Fix a regression in 3.5.5 when checking for execute permissions in + execve(2) and access(2). + Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256972.html diff --git a/winsup/cygwin/sec/base.cc b/winsup/cygwin/sec/base.cc index 2e50ce0c38b1..7c94f1402872 100644 --- a/winsup/cygwin/sec/base.cc +++ b/winsup/cygwin/sec/base.cc @@ -603,8 +603,14 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping, int check_file_access (path_conv &pc, int flags, bool effective) { - int ret = -1; ACCESS_MASK desired = 0; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + NTSTATUS status; + HANDLE h = NULL; + ULONG opts = 0; + int ret = -1; + if (flags & R_OK) desired |= FILE_READ_DATA; if (flags & W_OK) @@ -612,16 +618,23 @@ check_file_access (path_conv &pc, int flags, bool effective) if (flags & X_OK) desired |= FILE_EXECUTE; + /* For R_OK and W_OK we check with FILE_OPEN_FOR_BACKUP_INTENT since + we want to enable the full power of backup/restore privileges. + For X_OK, drop the FILE_OPEN_FOR_BACKUP_INTENT flag. If the caller + holds SE_BACKUP_PRIVILEGE, FILE_OPEN_FOR_BACKUP_INTENT opens the file, + no matter what access is requested. + For directories, FILE_OPEN_FOR_BACKUP_INTENT flag is always required. */ + if (!(flags & X_OK) || pc.isdir ()) + opts = FILE_OPEN_FOR_BACKUP_INTENT; + else /* For a regular file to be executable, it must also be readable. */ + desired |= FILE_READ_DATA; + if (!effective) cygheap->user.deimpersonate (); - OBJECT_ATTRIBUTES attr; pc.init_reopen_attr (attr, pc.handle ()); - NTSTATUS status; - IO_STATUS_BLOCK io; - HANDLE h; - status = NtOpenFile (&h, desired, &attr, &io, FILE_SHARE_VALID_FLAGS, - FILE_OPEN_FOR_BACKUP_INTENT); + + status = NtOpenFile (&h, desired, &attr, &io, FILE_SHARE_VALID_FLAGS, opts); if (NT_SUCCESS (status)) { NtClose (h);
