|
|
83e84cf |
From 30f5d0522a753d683bf5a216754ce4c499c98b4e Mon Sep 17 00:00:00 2001
|
|
|
83e84cf |
From: Peter Stephenson <pws@zsh.org>
|
|
|
83e84cf |
Date: Tue, 9 May 2017 17:49:18 +0100
|
|
|
83e84cf |
Subject: [PATCH 2/2] 40181: Fix buffer overrun in xsymlinks.
|
|
|
83e84cf |
|
|
|
83e84cf |
There was no check for copying to the internal xbuf2 for a
|
|
|
83e84cf |
preliminary test.
|
|
|
83e84cf |
|
|
|
83e84cf |
Upstream-commit: c7a9cf465dd620ef48d586026944d9bd7a0d5d6d
|
|
|
83e84cf |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
83e84cf |
---
|
|
|
83e84cf |
Src/utils.c | 14 +++++++++++---
|
|
|
83e84cf |
Test/D02glob.ztst | 8 ++++++++
|
|
|
83e84cf |
2 files changed, 19 insertions(+), 3 deletions(-)
|
|
|
83e84cf |
|
|
|
83e84cf |
diff --git a/Src/utils.c b/Src/utils.c
|
|
|
83e84cf |
index 7f3ddad..a54e310 100644
|
|
|
83e84cf |
--- a/Src/utils.c
|
|
|
83e84cf |
+++ b/Src/utils.c
|
|
|
83e84cf |
@@ -886,7 +886,7 @@ xsymlinks(char *s, int full)
|
|
|
83e84cf |
char **pp, **opp;
|
|
|
83e84cf |
char xbuf2[PATH_MAX*3+1], xbuf3[PATH_MAX*2+1];
|
|
|
83e84cf |
int t0, ret = 0;
|
|
|
83e84cf |
- zulong xbuflen = strlen(xbuf);
|
|
|
83e84cf |
+ zulong xbuflen = strlen(xbuf), pplen;
|
|
|
83e84cf |
|
|
|
83e84cf |
opp = pp = slashsplit(s);
|
|
|
83e84cf |
for (; xbuflen < sizeof(xbuf) && *pp && ret >= 0; pp++) {
|
|
|
83e84cf |
@@ -907,10 +907,18 @@ xsymlinks(char *s, int full)
|
|
|
83e84cf |
xbuflen--;
|
|
|
83e84cf |
continue;
|
|
|
83e84cf |
}
|
|
|
83e84cf |
- sprintf(xbuf2, "%s/%s", xbuf, *pp);
|
|
|
83e84cf |
+ /* Includes null byte. */
|
|
|
83e84cf |
+ pplen = strlen(*pp) + 1;
|
|
|
83e84cf |
+ if (xbuflen + pplen + 1 > sizeof(xbuf2)) {
|
|
|
83e84cf |
+ *xbuf = 0;
|
|
|
83e84cf |
+ ret = -1;
|
|
|
83e84cf |
+ break;
|
|
|
83e84cf |
+ }
|
|
|
83e84cf |
+ memcpy(xbuf2, xbuf, xbuflen);
|
|
|
83e84cf |
+ xbuf2[xbuflen] = '/';
|
|
|
83e84cf |
+ memcpy(xbuf2 + xbuflen + 1, *pp, pplen);
|
|
|
83e84cf |
t0 = readlink(unmeta(xbuf2), xbuf3, PATH_MAX);
|
|
|
83e84cf |
if (t0 == -1) {
|
|
|
83e84cf |
- zulong pplen = strlen(*pp) + 1;
|
|
|
83e84cf |
if ((xbuflen += pplen) < sizeof(xbuf)) {
|
|
|
83e84cf |
strcat(xbuf, "/");
|
|
|
83e84cf |
strcat(xbuf, *pp);
|
|
|
83e84cf |
diff --git a/Test/D02glob.ztst b/Test/D02glob.ztst
|
|
|
83e84cf |
index 1385d57..b958970 100644
|
|
|
83e84cf |
--- a/Test/D02glob.ztst
|
|
|
83e84cf |
+++ b/Test/D02glob.ztst
|
|
|
83e84cf |
@@ -686,3 +686,11 @@
|
|
|
83e84cf |
rm glob.tmp/link
|
|
|
83e84cf |
0:modifier ':P' resolves symlinks before '..' components
|
|
|
83e84cf |
*>*glob.tmp/hello/world
|
|
|
83e84cf |
+
|
|
|
83e84cf |
+ # This is a bit brittle as it depends on PATH_MAX.
|
|
|
83e84cf |
+ # We could use sysconf..
|
|
|
83e84cf |
+ bad_pwd="/${(l:16000:: :):-}"
|
|
|
83e84cf |
+ print ${bad_pwd:P}
|
|
|
83e84cf |
+0:modifier ':P' with path too long
|
|
|
83e84cf |
+?(eval):4: path expansion failed, using root directory
|
|
|
83e84cf |
+>/
|
|
|
83e84cf |
--
|
|
|
83e84cf |
2.14.3
|
|
|
83e84cf |
|