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