From 73eade866e0f1685749c0ec50f49fed0cca0c503 Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Fri, 25 Dec 2015 00:31:32 -0800 Subject: [PATCH 1/2] 37435 (+ fix typo): allow execution of empty files as "sh" scripts Upstream-commit: fc344465f27cdf89664a64fb157b7606c9eb837f Signed-off-by: Kamil Dudka --- Src/exec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Src/exec.c b/Src/exec.c index b9ffb35..f20b96c 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -465,9 +465,10 @@ zexecve(char *pth, char **argv, char **newenvp) if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) { argv0 = *argv; *argv = pth; + execvebuf[0] = '\0'; ct = read(fd, execvebuf, POUNDBANGLIMIT); close(fd); - if (ct > 0) { + if (ct >= 0) { if (execvebuf[0] == '#') { if (execvebuf[1] == '!') { for (t0 = 0; t0 != ct; t0++) -- 2.17.2 From ddb6c5b4c0ab9c6a7404112d367f0c7cc400ceec Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 3 Sep 2018 14:39:25 +0000 Subject: [PATCH 2/2] CVE-2018-0502, CVE-2018-13259: Fix two security issues in shebang line parsing. See NEWS for more information. Patch by Anthony Sottile and Buck Evan. Upstream-commit: 1c4c7b6a4d17294df028322b70c53803a402233d Signed-off-by: Kamil Dudka --- Src/exec.c | 32 ++++++++++++++++++-------------- Test/A05execution.ztst | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/Src/exec.c b/Src/exec.c index f20b96c..c95667e 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -427,7 +427,7 @@ execcursh(Estate state, int do_exec) /* execve after handling $_ and #! */ -#define POUNDBANGLIMIT 64 +#define POUNDBANGLIMIT 128 /**/ static int @@ -465,18 +465,20 @@ zexecve(char *pth, char **argv, char **newenvp) if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) { argv0 = *argv; *argv = pth; - execvebuf[0] = '\0'; + memset(execvebuf, '\0', POUNDBANGLIMIT + 1); ct = read(fd, execvebuf, POUNDBANGLIMIT); close(fd); if (ct >= 0) { - if (execvebuf[0] == '#') { - if (execvebuf[1] == '!') { - for (t0 = 0; t0 != ct; t0++) - if (execvebuf[t0] == '\n') - break; + if (ct >= 2 && execvebuf[0] == '#' && execvebuf[1] == '!') { + for (t0 = 0; t0 != ct; t0++) + if (execvebuf[t0] == '\n') + break; + if (t0 == ct) + zerr("%s: bad interpreter: %s: %e", pth, + execvebuf + 2, eno); + else { while (inblank(execvebuf[t0])) execvebuf[t0--] = '\0'; - execvebuf[POUNDBANGLIMIT] = '\0'; for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++); for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++); if (eno == ENOENT) { @@ -485,9 +487,14 @@ zexecve(char *pth, char **argv, char **newenvp) *ptr = '\0'; if (*ptr2 != '/' && (pprog = pathprog(ptr2, NULL))) { - argv[-2] = ptr2; - argv[-1] = ptr + 1; - execve(pprog, argv - 2, newenvp); + if (ptr == execvebuf + t0 + 1) { + argv[-1] = ptr2; + execve(pprog, argv - 1, newenvp); + } else { + argv[-2] = ptr2; + argv[-1] = ptr + 1; + execve(pprog, argv - 2, newenvp); + } } zerr("%s: bad interpreter: %s: %e", pth, ptr2, eno); @@ -500,9 +507,6 @@ zexecve(char *pth, char **argv, char **newenvp) argv[-1] = ptr2; execve(ptr2, argv - 1, newenvp); } - } else if (eno == ENOEXEC) { - argv[-1] = "sh"; - execve("/bin/sh", argv - 1, newenvp); } } else if (eno == ENOEXEC) { for (t0 = 0; t0 != ct; t0++) diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst index 0804691..fb39d05 100644 --- a/Test/A05execution.ztst +++ b/Test/A05execution.ztst @@ -12,7 +12,14 @@ print '#!/bin/sh\necho This is dir2' >dir2/tstcmd + print -n '#!sh\necho This is slashless' >tstcmd-slashless + print -n '#!echo foo\necho This is arg' >tstcmd-arg + print '#!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnyyy' >tstcmd-interp-too-long + print '#!/bin/sh\necho should not execute; exit 1' >xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn + chmod 755 tstcmd dir1/tstcmd dir2/tstcmd + chmod 755 tstcmd-slashless tstcmd-arg tstcmd-interp-too-long + chmod 755 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn %test ./tstcmd @@ -33,6 +40,21 @@ 0:path (2) >This is top + PATH=/bin:${ZTST_testdir}/command.tmp/ tstcmd-slashless +0:path (3) +>This is slashless + + PATH=/bin:${ZTST_testdir}/command.tmp tstcmd-arg +0:path (4) +*>foo */command.tmp/tstcmd-arg + + path=(/bin ${ZTST_testdir}/command.tmp/) + tstcmd-interp-too-long 2>&1; echo "status $?" + path=($storepath) +0:path (5) +*>*tstcmd-interp-too-long: bad interpreter: x*xn: no such file or directory +>status 127 + functst() { print $# arguments:; print -l $*; } functst "Eines Morgens" "als Gregor Samsa" functst "" -- 2.17.1