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);

Reply via email to