https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=98669a24760a84bfef498fedeef7fa7ecc518e6c

commit 98669a24760a84bfef498fedeef7fa7ecc518e6c
Author: Corinna Vinschen <[email protected]>
Date:   Tue Aug 6 10:46:31 2019 +0200

    Cygwin: exec: check execute bit prior to evaluating script
    
    When the exec family of functions is called for a script-like
    file, the av::setup function handles the exec[vl]p case as
    well.  The execve case for files not starting with a she-bang
    is handled first by returning ENOEXEC.  Only after that, the
    file's executability is checked.
    
    This leads to the problem that ENOEXEC is returned for non-executable
    files as well.  A calling shell interprets this as a file it should try
    to run as script.  This is not desired for non-executable files.
    
    Fix this problem by checking the file for executability first.  Only
    after that, follow the other potential code paths.
    
    Signed-off-by: Corinna Vinschen <[email protected]>

Diff:
---
 winsup/cygwin/spawn.cc | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 7f7af44..d957728 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -1172,6 +1172,12 @@ av::setup (const char *prog_arg, path_conv& real_path, 
const char *ext,
          }
        UnmapViewOfFile (buf);
   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, true) < 0)
+         return -1;    /* errno is already set. */
+
        if (!pgm)
          {
            if (!p_type_exec)
@@ -1188,12 +1194,6 @@ av::setup (const char *prog_arg, path_conv& real_path, 
const char *ext,
            arg1 = NULL;
          }
 
-       /* 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, true) < 0)
-         return -1;    /* errno is already set. */
-
        /* Replace argv[0] with the full path to the script if this is the
           first time through the loop. */
        replace0_maybe (prog_arg);

Reply via email to