Blob Blame History Raw
From e51be32e198f42828b1082f9a40ff525ba892dcb Mon Sep 17 00:00:00 2001
From: "Barton E. Schaefer" <schaefer@zsh.org>
Date: Sun, 17 Aug 2014 10:32:02 -0700
Subject: [PATCH 1/2] Increase size of xbuf2 in xsymlinks to make gcc
 FORTIFY_SOURCE=2 happy.

Upstream-commit: 4ba08eef7e15f7fd0c96353d931b764e25fd251d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
 Src/utils.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Src/utils.c b/Src/utils.c
index a197ef8..13e744e 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -724,7 +724,7 @@ static int
 xsymlinks(char *s)
 {
     char **pp, **opp;
-    char xbuf2[PATH_MAX*2], xbuf3[PATH_MAX*2];
+    char xbuf2[PATH_MAX*3], xbuf3[PATH_MAX*2];
     int t0, ret = 0;
     zulong xbuflen = strlen(xbuf);
 
-- 
2.14.3


From 5059305b758f1fd228837da436b48a1dcadfd7a3 Mon Sep 17 00:00:00 2001
From: Peter Stephenson <pws@zsh.org>
Date: Tue, 9 May 2017 17:49:18 +0100
Subject: [PATCH 2/2] 40181: Fix buffer overrun in xsymlinks.

There was no check for copying to the internal xbuf2 for a
preliminary test.

Upstream-commit: c7a9cf465dd620ef48d586026944d9bd7a0d5d6d

The upstream test-case has not been backported because this version
of zsh does not support the :P modifier.

Signed-off-by: Kamil Dudka <kdudka@redhat.com>

Also picked a fix for buffer size off-by-one from upstream commit
a62e1640bcafbb82d86ea8d8ce057a83c4683d60 to fix the following defect
newly detected by Coverity Analysis:

Error: OVERRUN (CWE-119):
zsh-5.0.2/Src/utils.c:732: cond_at_most: Checking "xbuflen < 8192UL" implies that "xbuflen" may be up to 8191 on the true branch.
zsh-5.0.2/Src/utils.c:757: overrun-local: Overrunning array of 8192 bytes at byte offset 8192 by dereferencing pointer "xbuf2 + xbuflen + 1". [Note: The source code implementation of the function has been overridden by a builtin model.]
---
 Src/utils.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/Src/utils.c b/Src/utils.c
index a197ef8..391d020 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -684,7 +684,7 @@ ispwd(char *s)
     return 0;
 }
 
-static char xbuf[PATH_MAX*2];
+static char xbuf[PATH_MAX*2+1];
 
 /**/
 static char **
@@ -724,9 +724,9 @@ static int
 xsymlinks(char *s)
 {
     char **pp, **opp;
-    char xbuf2[PATH_MAX*3], xbuf3[PATH_MAX*2];
+    char xbuf2[PATH_MAX*3+1], xbuf3[PATH_MAX*2+1];
     int t0, ret = 0;
-    zulong xbuflen = strlen(xbuf);
+    zulong xbuflen = strlen(xbuf), pplen;
 
     opp = pp = slashsplit(s);
     for (; xbuflen < sizeof(xbuf) && *pp; pp++) {
@@ -745,10 +745,18 @@ xsymlinks(char *s)
 	    *p = '\0';
 	    continue;
 	}
-	sprintf(xbuf2, "%s/%s", xbuf, *pp);
+	/* Includes null byte. */
+	pplen = strlen(*pp) + 1;
+	if (xbuflen + pplen + 1 > sizeof(xbuf2)) {
+	    *xbuf = 0;
+	    ret = -1;
+	    break;
+	}
+	memcpy(xbuf2, xbuf, xbuflen);
+	xbuf2[xbuflen] = '/';
+	memcpy(xbuf2 + xbuflen + 1, *pp, pplen);
 	t0 = readlink(unmeta(xbuf2), xbuf3, PATH_MAX);
 	if (t0 == -1) {
-	    zulong pplen = strlen(*pp) + 1;
 	    if ((xbuflen += pplen) < sizeof(xbuf)) {
 		strcat(xbuf, "/");
 		strcat(xbuf, *pp);
-- 
2.14.3