From e51be32e198f42828b1082f9a40ff525ba892dcb Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" 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 --- 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 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 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