After the commit a0933cd17d19, access(_, X_OK) returns 0 for the
file without execution permission if the account is administrator
while it should return -1. The Administrator has full access
permission regardless of ACL, however, access() should return -1
if execution permission is set for neither user, group nor others,
even though NtOpenFile() succeeds. This patch checks result of
stat() before calling NtOpenFile() when the X_OK permissions is
specified for access().

Addresses: https://cygwin.com/pipermail/cygwin/2024-December/256972.html
Fixes: a0933cd17d19 ("Correction for samba/SMB share")
Reported-by: Bruno Haible <br...@clisp.org>
Reviewed-by:
Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp>
---
 winsup/cygwin/sec/base.cc | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/winsup/cygwin/sec/base.cc b/winsup/cygwin/sec/base.cc
index 647c27ec6..666d257e3 100644
--- a/winsup/cygwin/sec/base.cc
+++ b/winsup/cygwin/sec/base.cc
@@ -613,6 +613,22 @@ check_file_access (path_conv &pc, int flags, bool 
effective)
   if (flags & X_OK)
     desired |= FILE_EXECUTE;
 
+  /* The Administrator has full access permission regardless of ACL,
+     however, access() should return -1 if 'x' permission is set
+     for neither user, group nor others, even though NtOpenFile()
+     succeeds. */
+  if ((flags & X_OK) && !pc.isdir ())
+    {
+      struct stat st;
+      if (stat (pc.get_posix (), &st))
+       goto out;
+      else if ((st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)
+       {
+         set_errno (EACCES);
+         goto out;
+       }
+    }
+
   if (!effective)
     cygheap->user.deimpersonate ();
 
@@ -634,6 +650,7 @@ check_file_access (path_conv &pc, int flags, bool effective)
   if (!effective)
     cygheap->user.reimpersonate ();
 
+out:
   debug_printf ("flags %y, ret %d", flags, ret);
   return ret;
 }
-- 
2.45.1

Reply via email to