diff options
author | jilles <jilles@FreeBSD.org> | 2011-02-05 12:54:59 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2011-02-05 12:54:59 +0000 |
commit | a81357fbe93ddb2be80ff1401450234c412c135d (patch) | |
tree | 999ded504b6f93787ff21b0740db2574608bc758 /bin | |
parent | fa5090f1ddeff2b8b1efa2d3c21c5ba6b70e8fba (diff) | |
download | FreeBSD-src-a81357fbe93ddb2be80ff1401450234c412c135d.zip FreeBSD-src-a81357fbe93ddb2be80ff1401450234c412c135d.tar.gz |
sh: Do not try to execute binary files as scripts.
If execve() returns an [ENOEXEC] error, check if the file is binary before
trying to execute it using sh. A file is considered binary if at least one
of the first 256 bytes is '\0'.
In particular, trying to execute ELF binaries for the wrong architecture now
fails with an "Exec format error" message instead of syntax errors and
potentially strange results.
Diffstat (limited to 'bin')
-rw-r--r-- | bin/sh/exec.c | 16 | ||||
-rw-r--r-- | bin/sh/sh.1 | 1 |
2 files changed, 16 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. |