|
|
8de4c6 |
From ddb6c5b4c0ab9c6a7404112d367f0c7cc400ceec Mon Sep 17 00:00:00 2001
|
|
|
8de4c6 |
From: Anthony Sottile <asottile@umich.edu>
|
|
|
8de4c6 |
Date: Mon, 3 Sep 2018 14:39:25 +0000
|
|
|
8de4c6 |
Subject: [PATCH] CVE-2018-0502, CVE-2018-13259: Fix two security issues in
|
|
|
8de4c6 |
shebang line parsing.
|
|
|
8de4c6 |
|
|
|
8de4c6 |
See NEWS for more information.
|
|
|
8de4c6 |
|
|
|
8de4c6 |
Patch by Anthony Sottile and Buck Evan.
|
|
|
8de4c6 |
|
|
|
8de4c6 |
Upstream-commit: 1c4c7b6a4d17294df028322b70c53803a402233d
|
|
|
8de4c6 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
8de4c6 |
---
|
|
|
8de4c6 |
Etc/FAQ.yo | 2 +-
|
|
|
8de4c6 |
Src/exec.c | 36 ++++++++++++++++++++----------------
|
|
|
8de4c6 |
Test/A05execution.ztst | 22 ++++++++++++++++++++++
|
|
|
8de4c6 |
3 files changed, 43 insertions(+), 17 deletions(-)
|
|
|
8de4c6 |
|
|
|
8de4c6 |
diff --git a/Etc/FAQ.yo b/Etc/FAQ.yo
|
|
|
8de4c6 |
index 72ff7fa..8552fe7 100644
|
|
|
8de4c6 |
--- a/Etc/FAQ.yo
|
|
|
8de4c6 |
+++ b/Etc/FAQ.yo
|
|
|
8de4c6 |
@@ -306,7 +306,7 @@ sect(On what machines will it run?)
|
|
|
8de4c6 |
|
|
|
8de4c6 |
sect(What's the latest version?)
|
|
|
8de4c6 |
|
|
|
8de4c6 |
- Zsh 5.5.1 is the latest production version. For details of all the
|
|
|
8de4c6 |
+ Zsh 5.6 is the latest production version. For details of all the
|
|
|
8de4c6 |
changes, see the NEWS file in the source distribution.
|
|
|
8de4c6 |
|
|
|
8de4c6 |
A beta of the next version is sometimes available. Development of zsh is
|
|
|
8de4c6 |
diff --git a/Src/exec.c b/Src/exec.c
|
|
|
8de4c6 |
index 216057a..0908a1a 100644
|
|
|
8de4c6 |
--- a/Src/exec.c
|
|
|
8de4c6 |
+++ b/Src/exec.c
|
|
|
8de4c6 |
@@ -453,7 +453,7 @@ execcursh(Estate state, int do_exec)
|
|
|
8de4c6 |
|
|
|
8de4c6 |
/* execve after handling $_ and #! */
|
|
|
8de4c6 |
|
|
|
8de4c6 |
-#define POUNDBANGLIMIT 64
|
|
|
8de4c6 |
+#define POUNDBANGLIMIT 128
|
|
|
8de4c6 |
|
|
|
8de4c6 |
/**/
|
|
|
8de4c6 |
static int
|
|
|
8de4c6 |
@@ -494,18 +494,20 @@ zexecve(char *pth, char **argv, char **newenvp)
|
|
|
8de4c6 |
if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) {
|
|
|
8de4c6 |
argv0 = *argv;
|
|
|
8de4c6 |
*argv = pth;
|
|
|
8de4c6 |
- execvebuf[0] = '\0';
|
|
|
8de4c6 |
+ memset(execvebuf, '\0', POUNDBANGLIMIT + 1);
|
|
|
8de4c6 |
ct = read(fd, execvebuf, POUNDBANGLIMIT);
|
|
|
8de4c6 |
close(fd);
|
|
|
8de4c6 |
if (ct >= 0) {
|
|
|
8de4c6 |
- if (execvebuf[0] == '#') {
|
|
|
8de4c6 |
- if (execvebuf[1] == '!') {
|
|
|
8de4c6 |
- for (t0 = 0; t0 != ct; t0++)
|
|
|
8de4c6 |
- if (execvebuf[t0] == '\n')
|
|
|
8de4c6 |
- break;
|
|
|
8de4c6 |
+ if (ct >= 2 && execvebuf[0] == '#' && execvebuf[1] == '!') {
|
|
|
8de4c6 |
+ for (t0 = 0; t0 != ct; t0++)
|
|
|
8de4c6 |
+ if (execvebuf[t0] == '\n')
|
|
|
8de4c6 |
+ break;
|
|
|
8de4c6 |
+ if (t0 == ct)
|
|
|
8de4c6 |
+ zerr("%s: bad interpreter: %s: %e", pth,
|
|
|
8de4c6 |
+ execvebuf + 2, eno);
|
|
|
8de4c6 |
+ else {
|
|
|
8de4c6 |
while (inblank(execvebuf[t0]))
|
|
|
8de4c6 |
execvebuf[t0--] = '\0';
|
|
|
8de4c6 |
- execvebuf[POUNDBANGLIMIT] = '\0';
|
|
|
8de4c6 |
for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
|
|
|
8de4c6 |
for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
|
|
|
8de4c6 |
if (eno == ENOENT) {
|
|
|
8de4c6 |
@@ -514,10 +516,16 @@ zexecve(char *pth, char **argv, char **newenvp)
|
|
|
8de4c6 |
*ptr = '\0';
|
|
|
8de4c6 |
if (*ptr2 != '/' &&
|
|
|
8de4c6 |
(pprog = pathprog(ptr2, NULL))) {
|
|
|
8de4c6 |
- argv[-2] = ptr2;
|
|
|
8de4c6 |
- argv[-1] = ptr + 1;
|
|
|
8de4c6 |
- winch_unblock();
|
|
|
8de4c6 |
- execve(pprog, argv - 2, newenvp);
|
|
|
8de4c6 |
+ if (ptr == execvebuf + t0 + 1) {
|
|
|
8de4c6 |
+ argv[-1] = ptr2;
|
|
|
8de4c6 |
+ winch_unblock();
|
|
|
8de4c6 |
+ execve(pprog, argv - 1, newenvp);
|
|
|
8de4c6 |
+ } else {
|
|
|
8de4c6 |
+ argv[-2] = ptr2;
|
|
|
8de4c6 |
+ argv[-1] = ptr + 1;
|
|
|
8de4c6 |
+ winch_unblock();
|
|
|
8de4c6 |
+ execve(pprog, argv - 2, newenvp);
|
|
|
8de4c6 |
+ }
|
|
|
8de4c6 |
}
|
|
|
8de4c6 |
zerr("%s: bad interpreter: %s: %e", pth, ptr2,
|
|
|
8de4c6 |
eno);
|
|
|
8de4c6 |
@@ -532,10 +540,6 @@ zexecve(char *pth, char **argv, char **newenvp)
|
|
|
8de4c6 |
winch_unblock();
|
|
|
8de4c6 |
execve(ptr2, argv - 1, newenvp);
|
|
|
8de4c6 |
}
|
|
|
8de4c6 |
- } else if (eno == ENOEXEC) {
|
|
|
8de4c6 |
- argv[-1] = "sh";
|
|
|
8de4c6 |
- winch_unblock();
|
|
|
8de4c6 |
- execve("/bin/sh", argv - 1, newenvp);
|
|
|
8de4c6 |
}
|
|
|
8de4c6 |
} else if (eno == ENOEXEC) {
|
|
|
8de4c6 |
for (t0 = 0; t0 != ct; t0++)
|
|
|
8de4c6 |
diff --git a/Test/A05execution.ztst b/Test/A05execution.ztst
|
|
|
8de4c6 |
index 0804691..fb39d05 100644
|
|
|
8de4c6 |
--- a/Test/A05execution.ztst
|
|
|
8de4c6 |
+++ b/Test/A05execution.ztst
|
|
|
8de4c6 |
@@ -12,7 +12,14 @@
|
|
|
8de4c6 |
|
|
|
8de4c6 |
print '#!/bin/sh\necho This is dir2' >dir2/tstcmd
|
|
|
8de4c6 |
|
|
|
8de4c6 |
+ print -n '#!sh\necho This is slashless' >tstcmd-slashless
|
|
|
8de4c6 |
+ print -n '#!echo foo\necho This is arg' >tstcmd-arg
|
|
|
8de4c6 |
+ print '#!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnyyy' >tstcmd-interp-too-long
|
|
|
8de4c6 |
+ print '#!/bin/sh\necho should not execute; exit 1' >xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn
|
|
|
8de4c6 |
+
|
|
|
8de4c6 |
chmod 755 tstcmd dir1/tstcmd dir2/tstcmd
|
|
|
8de4c6 |
+ chmod 755 tstcmd-slashless tstcmd-arg tstcmd-interp-too-long
|
|
|
8de4c6 |
+ chmod 755 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn
|
|
|
8de4c6 |
|
|
|
8de4c6 |
%test
|
|
|
8de4c6 |
./tstcmd
|
|
|
8de4c6 |
@@ -33,6 +40,21 @@
|
|
|
8de4c6 |
0:path (2)
|
|
|
8de4c6 |
>This is top
|
|
|
8de4c6 |
|
|
|
8de4c6 |
+ PATH=/bin:${ZTST_testdir}/command.tmp/ tstcmd-slashless
|
|
|
8de4c6 |
+0:path (3)
|
|
|
8de4c6 |
+>This is slashless
|
|
|
8de4c6 |
+
|
|
|
8de4c6 |
+ PATH=/bin:${ZTST_testdir}/command.tmp tstcmd-arg
|
|
|
8de4c6 |
+0:path (4)
|
|
|
8de4c6 |
+*>foo */command.tmp/tstcmd-arg
|
|
|
8de4c6 |
+
|
|
|
8de4c6 |
+ path=(/bin ${ZTST_testdir}/command.tmp/)
|
|
|
8de4c6 |
+ tstcmd-interp-too-long 2>&1; echo "status $?"
|
|
|
8de4c6 |
+ path=($storepath)
|
|
|
8de4c6 |
+0:path (5)
|
|
|
8de4c6 |
+*>*tstcmd-interp-too-long: bad interpreter: x*xn: no such file or directory
|
|
|
8de4c6 |
+>status 127
|
|
|
8de4c6 |
+
|
|
|
8de4c6 |
functst() { print $# arguments:; print -l $*; }
|
|
|
8de4c6 |
functst "Eines Morgens" "als Gregor Samsa"
|
|
|
8de4c6 |
functst ""
|
|
|
8de4c6 |
--
|
|
|
8de4c6 |
2.17.1
|
|
|
8de4c6 |
|