From owner-svn-src-all@FreeBSD.ORG Sat Feb 5 12:55:00 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4AB52106566B; Sat, 5 Feb 2011 12:55:00 +0000 (UTC) (envelope-from jilles@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1E7D08FC0A; Sat, 5 Feb 2011 12:55:00 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p15Ct0dt028288; Sat, 5 Feb 2011 12:55:00 GMT (envelope-from jilles@svn.freebsd.org) Received: (from jilles@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p15Csxip028284; Sat, 5 Feb 2011 12:54:59 GMT (envelope-from jilles@svn.freebsd.org) Message-Id: <201102051254.p15Csxip028284@svn.freebsd.org> From: Jilles Tjoelker Date: Sat, 5 Feb 2011 12:54:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218320 - in head: bin/sh tools/regression/bin/sh/errors X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 05 Feb 2011 12:55:00 -0000 Author: jilles Date: Sat Feb 5 12:54:59 2011 New Revision: 218320 URL: http://svn.freebsd.org/changeset/base/218320 Log: 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. Added: head/tools/regression/bin/sh/errors/bad-binary1.126 (contents, props changed) Modified: head/bin/sh/exec.c head/bin/sh/sh.1 Modified: head/bin/sh/exec.c ============================================================================== --- head/bin/sh/exec.c Sat Feb 5 12:12:51 2011 (r218319) +++ head/bin/sh/exec.c Sat Feb 5 12:54:59 2011 (r218320) @@ -126,6 +126,8 @@ shellexec(char **argv, char **envp, cons 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, cons 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); Modified: head/bin/sh/sh.1 ============================================================================== --- head/bin/sh/sh.1 Sat Feb 5 12:12:51 2011 (r218319) +++ head/bin/sh/sh.1 Sat Feb 5 12:54:59 2011 (r218320) @@ -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. Added: head/tools/regression/bin/sh/errors/bad-binary1.126 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/tools/regression/bin/sh/errors/bad-binary1.126 Sat Feb 5 12:54:59 2011 (r218320) @@ -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