Hi, In glibc versions < 2.15, posix_spawn and posix_spawnp did execute a script (with execution bits set) even if it did not start with a '#!' marker. Then, /bin/sh was used as an interpreter.
You can imagine how easily a text file, which happens to set execution bits set because it was copied from a samba/cifs mount, can get executed. Apparently this is considered unsecure, and since POSIX <https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html> is silent on this aspect, this misfeature was withdrawn from glibc in <https://sourceware.org/bugzilla/show_bug.cgi?id=13134> and <https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=d96de9634a334af16c0ac711074c15ac1762b23c>. But the test programs that I wrote for this show that, unlike on GNU/Linux, on GNU/Hurd such scripts are still executed. How to reproduce: 1) Preparations: $ echo ':' > conftest.scr $ chmod a+x conftest.scr 2) Test case for posix_spawn: #include <errno.h> #include <spawn.h> #include <stddef.h> #include <sys/types.h> #include <sys/wait.h> int main () { const char *prog_path = "./conftest.scr"; const char *prog_argv[2] = { prog_path, NULL }; const char *environment[2] = { "PATH=.", NULL }; pid_t child; int status; int err = posix_spawn (&child, prog_path, NULL, NULL, (char **) prog_argv, (char **) environment); if (err == ENOEXEC) return 0; if (err != 0) return 1; status = 0; while (waitpid (child, &status, 0) != child) ; if (!WIFEXITED (status)) return 2; if (WEXITSTATUS (status) != 127) return 3; return 0; } 3) Test case for posix_spawnp: #include <errno.h> #include <spawn.h> #include <stddef.h> #include <sys/types.h> #include <sys/wait.h> int main () { const char *prog_path = "./conftest.scr"; const char *prog_argv[2] = { prog_path, NULL }; const char *environment[2] = { "PATH=.", NULL }; pid_t child; int status; int err = posix_spawnp (&child, prog_path, NULL, NULL, (char **) prog_argv, (char **) environment); if (err == ENOEXEC) return 0; if (err != 0) return 1; status = 0; while (waitpid (child, &status, 0) != child) ; if (!WIFEXITED (status)) return 2; if (WEXITSTATUS (status) != 127) return 3; return 0; } 4) Compile and run the program. Expected exit code: 0 Actual exit code: 3 You probably need strace to see what's happing under the hood. Seen on a glibc 2.28 system. Bruno