summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/exec.c16
-rw-r--r--bin/sh/sh.11
-rw-r--r--tools/regression/bin/sh/errors/bad-binary1.12612
3 files changed, 28 insertions, 1 deletions
diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index 07fa8bb..6297e9b 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 2ecdcf0..1a3124d 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 0000000..d92e9de
--- /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
OpenPOWER on IntegriCloud