1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-29 05:21:00 +01:00

40181: Fix buffer overrun in xsymlinks.

There was no check for copying to the internal xbuf2 for a
preliminary test.
This commit is contained in:
Peter Stephenson 2017-05-09 17:49:18 +01:00
parent 263a0c2476
commit c7a9cf465d
3 changed files with 22 additions and 3 deletions

View file

@ -1,5 +1,8 @@
2017-05-09 Peter Stephenson <p.stephenson@samsung.com> 2017-05-09 Peter Stephenson <p.stephenson@samsung.com>
* 41081: Src/utils.c, Test/D02glob.ztst: Symlink expansion
didn't test all buffer length calculations.
* 41078: Src/prompt.c, Test/D01prompt.ztst: Empty psvar could * 41078: Src/prompt.c, Test/D01prompt.ztst: Empty psvar could
cause bad reference in prompt expansion. cause bad reference in prompt expansion.

View file

@ -886,7 +886,7 @@ xsymlinks(char *s, int full)
char **pp, **opp; char **pp, **opp;
char xbuf2[PATH_MAX*3+1], xbuf3[PATH_MAX*2+1]; char xbuf2[PATH_MAX*3+1], xbuf3[PATH_MAX*2+1];
int t0, ret = 0; int t0, ret = 0;
zulong xbuflen = strlen(xbuf); zulong xbuflen = strlen(xbuf), pplen;
opp = pp = slashsplit(s); opp = pp = slashsplit(s);
for (; xbuflen < sizeof(xbuf) && *pp && ret >= 0; pp++) { for (; xbuflen < sizeof(xbuf) && *pp && ret >= 0; pp++) {
@ -907,10 +907,18 @@ xsymlinks(char *s, int full)
xbuflen--; xbuflen--;
continue; 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); t0 = readlink(unmeta(xbuf2), xbuf3, PATH_MAX);
if (t0 == -1) { if (t0 == -1) {
zulong pplen = strlen(*pp) + 1;
if ((xbuflen += pplen) < sizeof(xbuf)) { if ((xbuflen += pplen) < sizeof(xbuf)) {
strcat(xbuf, "/"); strcat(xbuf, "/");
strcat(xbuf, *pp); strcat(xbuf, *pp);

View file

@ -687,6 +687,14 @@
0:modifier ':P' resolves symlinks before '..' components 0:modifier ':P' resolves symlinks before '..' components
*>*glob.tmp/hello/world *>*glob.tmp/hello/world
# This is a bit brittle as it depends on PATH_MAX.
# We could use sysconf..
bad_pwd="/${(l:16000:: :):-}"
print ${bad_pwd:P}
0:modifier ':P' with path too long
?(eval):2: path expansion failed, using root directory
>/
foo=a foo=a
value="ac" value="ac"
print ${value//[${foo}b-z]/x} print ${value//[${foo}b-z]/x}