Blame SOURCES/0001-zsh-5.5.1-CVE-2018-0502-CVE-2018-13259.patch

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