The branch stable/12 has been updated by jilles:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3708b615c354df013037c065d5a714207c041ea8

commit 3708b615c354df013037c065d5a714207c041ea8
Author:     Jilles Tjoelker <jil...@freebsd.org>
AuthorDate: 2020-05-30 16:00:49 +0000
Commit:     Jilles Tjoelker <jil...@freebsd.org>
CommitDate: 2021-01-30 15:10:26 +0000

    sh: Allow more scripts without #!
    
    Austin Group bugs #1226 and #1250 changed the requirements for shell scripts
    without #! (POSIX does not specify #!; this is about the shell execution
    when execve(2) returns an [ENOEXEC] error).
    
    POSIX says we shall allow execution if the initial part intended to be
    parsed by the shell consists of characters and does not contain the NUL
    character.  This allows concatenating a shell script (ending with exec or
    exit) and a binary payload.
    
    In order to reject common binary files such as PNG images, check that there
    is a lowercase letter or expansion before the last newline before the NUL
    character, in addition to the check for the newline character suggested by
    POSIX.
    
    (cherry picked from commit e0f5c1387df23c8c4811f5b24a7ef6ecac51a71a)
---
 bin/sh/exec.c                       | 34 +++++++++++++++++++++++++++++++++-
 bin/sh/tests/execution/Makefile     |  1 +
 bin/sh/tests/execution/shellproc6.0 |  8 ++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/bin/sh/exec.c b/bin/sh/exec.c
index 95bf22a4a9f9..2bbef6ca0d27 100644
--- a/bin/sh/exec.c
+++ b/bin/sh/exec.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
 #include <fcntl.h>
 #include <errno.h>
 #include <paths.h>
+#include <stdbool.h>
 #include <stdlib.h>
 
 /*
@@ -144,6 +145,37 @@ shellexec(char **argv, char **envp, const char *path, int 
idx)
 }
 
 
+static bool
+isbinary(const char *data, size_t len)
+{
+       const char *nul, *p;
+       bool hasletter;
+
+       nul = memchr(data, '\0', len);
+       if (nul == NULL)
+               return false;
+       /*
+        * POSIX says we shall allow execution if the initial part intended
+        * to be parsed by the shell consists of characters and does not
+        * contain the NUL character. This allows concatenating a shell
+        * script (ending with exec or exit) and a binary payload.
+        *
+        * In order to reject common binary files such as PNG images, check
+        * that there is a lowercase letter or expansion before the last
+        * newline before the NUL character, in addition to the check for
+        * the newline character suggested by POSIX.
+        */
+       hasletter = false;
+       for (p = data; *p != '\0'; p++) {
+               if ((*p >= 'a' && *p <= 'z') || *p == '$' || *p == '`')
+                       hasletter = true;
+               if (hasletter && *p == '\n')
+                       return false;
+       }
+       return true;
+}
+
+
 static void
 tryexec(char *cmd, char **argv, char **envp)
 {
@@ -159,7 +191,7 @@ tryexec(char *cmd, char **argv, char **envp)
                if (in != -1) {
                        n = pread(in, buf, sizeof buf, 0);
                        close(in);
-                       if (n > 0 && memchr(buf, '\0', n) != NULL) {
+                       if (n > 0 && isbinary(buf, n)) {
                                errno = ENOEXEC;
                                return;
                        }
diff --git a/bin/sh/tests/execution/Makefile b/bin/sh/tests/execution/Makefile
index bd6b2e06d55e..c7f68a7404aa 100644
--- a/bin/sh/tests/execution/Makefile
+++ b/bin/sh/tests/execution/Makefile
@@ -60,6 +60,7 @@ ${PACKAGE}FILES+=             shellproc2.0
 ${PACKAGE}FILES+=              shellproc3.0
 ${PACKAGE}FILES+=              shellproc4.0
 ${PACKAGE}FILES+=              shellproc5.0
+${PACKAGE}FILES+=              shellproc6.0
 ${PACKAGE}FILES+=              subshell1.0 subshell1.0.stdout
 ${PACKAGE}FILES+=              subshell2.0
 ${PACKAGE}FILES+=              subshell3.0
diff --git a/bin/sh/tests/execution/shellproc6.0 
b/bin/sh/tests/execution/shellproc6.0
new file mode 100644
index 000000000000..1c06bc3b05a9
--- /dev/null
+++ b/bin/sh/tests/execution/shellproc6.0
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+T=`mktemp -d "${TMPDIR:-/tmp}/sh-test.XXXXXXXX"` || exit
+trap 'rm -rf "${T}"' 0
+printf 'printf "this "\necho is a test\nexit\n\0' >"$T/testshellproc"
+chmod 755 "$T/testshellproc"
+PATH=$T:$PATH
+[ "`testshellproc`" = "this is a test" ]
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to