diff options
-rw-r--r-- | bin/sh/exec.c | 16 | ||||
-rw-r--r-- | bin/sh/sh.1 | 1 | ||||
-rw-r--r-- | tools/regression/bin/sh/errors/bad-binary1.126 | 12 |
3 files changed, 28 insertions, 1 deletions
diff --git a/bin/sh/exec.c b/bin/sh/exec.c index 07fa8bb39051..6297e9b4b07f 100644 --- a/bin/sh/exec.c +++ b/bin/sh/exec.c @@ -126,6 +126,8 @@ shellexec(char **argv, char **envp, const char *path, int idx) tryexec(cmdname, argv, envp); if (errno != ENOENT && errno != ENOTDIR) e = errno; + if (e == ENOEXEC) + break; } stunalloc(cmdname); } @@ -145,11 +147,23 @@ shellexec(char **argv, char **envp, const char *path, int idx) static void tryexec(char *cmd, char **argv, char **envp) { - int e; + int e, in; + ssize_t n; + char buf[256]; execve(cmd, argv, envp); e = errno; if (e == ENOEXEC) { + INTOFF; + in = open(cmd, O_RDONLY | O_NONBLOCK); + if (in != -1) { + n = pread(in, buf, sizeof buf, 0); + close(in); + if (n > 0 && memchr(buf, '\0', n) != NULL) { + errno = ENOEXEC; + return; + } + } *argv = cmd; *--argv = _PATH_BSHELL; execve(_PATH_BSHELL, argv, envp); diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index 2ecdcf0c1ae1..1a3124dcf7a3 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -647,6 +647,7 @@ resulting in an .Er ENOEXEC return value from .Xr execve 2 ) +but appears to be a text file, the shell will run a new instance of .Nm to interpret it. diff --git a/tools/regression/bin/sh/errors/bad-binary1.126 b/tools/regression/bin/sh/errors/bad-binary1.126 new file mode 100644 index 000000000000..d92e9ded5689 --- /dev/null +++ b/tools/regression/bin/sh/errors/bad-binary1.126 @@ -0,0 +1,12 @@ +# $FreeBSD$ +# Checking for binary "scripts" without magic number is permitted but not +# required by POSIX. However, it is preferable to getting errors like +# Syntax error: word unexpected (expecting ")") +# from trying to execute ELF binaries for the wrong architecture. + +T=`mktemp -d "${TMPDIR:-/tmp}/sh-test.XXXXXXXX"` || exit +trap 'rm -rf "${T}"' 0 +printf '\0echo bad\n' >"$T/testshellproc" +chmod 755 "$T/testshellproc" +PATH=$T:$PATH +testshellproc 2>/dev/null |