mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-04 10:41:11 +02:00
CVE-2018-0502, CVE-2018-13259: Fix two security issues in shebang line parsing.
See NEWS for more information. Patch by Anthony Sottile and Buck Evan.
This commit is contained in:
parent
baef71ccfc
commit
1c4c7b6a4d
6 changed files with 72 additions and 20 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2018-09-03 Anthony Sottile <asottile@umich.edu>
|
||||||
|
|
||||||
|
* CVE-2018-0502, CVE-2018-13259: Fix two security issues in
|
||||||
|
shebang line parsing. [With Buck Evan]
|
||||||
|
|
||||||
2018-09-03 Daniel Shahaf <d.s@daniel.shahaf.name>
|
2018-09-03 Daniel Shahaf <d.s@daniel.shahaf.name>
|
||||||
|
|
||||||
* 43367: Makefile.in: Add maintainer targets 'tarxz-src' and
|
* 43367: Makefile.in: Add maintainer targets 'tarxz-src' and
|
||||||
|
|
|
@ -306,7 +306,7 @@ sect(On what machines will it run?)
|
||||||
|
|
||||||
sect(What's the latest version?)
|
sect(What's the latest version?)
|
||||||
|
|
||||||
Zsh 5.5.1 is the latest production version. For details of all the
|
Zsh 5.6 is the latest production version. For details of all the
|
||||||
changes, see the NEWS file in the source distribution.
|
changes, see the NEWS file in the source distribution.
|
||||||
|
|
||||||
A beta of the next version is sometimes available. Development of zsh is
|
A beta of the next version is sometimes available. Development of zsh is
|
||||||
|
|
21
NEWS
21
NEWS
|
@ -4,6 +4,27 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH
|
||||||
|
|
||||||
Note also the list of incompatibilities in the README file.
|
Note also the list of incompatibilities in the README file.
|
||||||
|
|
||||||
|
Changes from 5.5.1-test-2 to 5.6
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
CVE-2018-0502: Data from the second line of a #! script file might be passed to
|
||||||
|
execve(). For example, in the following situation -
|
||||||
|
.
|
||||||
|
printf '#!foo\nbar' > baz
|
||||||
|
./baz
|
||||||
|
.
|
||||||
|
the shell might take "bar" rather than "foo" for the argv[0] to be passed to
|
||||||
|
execve(). [ Reported by Anthony Sottile and Buck Evan. ]
|
||||||
|
|
||||||
|
CVE-2018-13259: A shebang line longer than 64 characters would be truncated.
|
||||||
|
For example, in the following situation:
|
||||||
|
.
|
||||||
|
( printf '#!'; repeat 64 printf 'x'; printf 'y' ) > foo
|
||||||
|
./foo
|
||||||
|
.
|
||||||
|
the shell might execute x...x (64 repetitions) rather than x...xy (64 x's,
|
||||||
|
one y). [ Reported by Daniel Shahaf. ]
|
||||||
|
|
||||||
Changes from 5.5.1 to 5.5.1-test-2
|
Changes from 5.5.1 to 5.5.1-test-2
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
|
|
6
README
6
README
|
@ -5,9 +5,9 @@ THE Z SHELL (ZSH)
|
||||||
Version
|
Version
|
||||||
-------
|
-------
|
||||||
|
|
||||||
This is version 5.5.1-test-2 of the shell. This is a test release. There
|
This is version 5.6 of the shell. This is a security and feature release.
|
||||||
are some significant bug fixes and a few user visible additions since
|
There are some significant bug fixes and a few user visible additions since
|
||||||
5.5.1. All zsh installations are encouraged to upgrade.
|
5.5.1. All zsh installations are encouraged to upgrade as soon as possible.
|
||||||
|
|
||||||
Note in particular the changes highlighted under "Incompatibilities since
|
Note in particular the changes highlighted under "Incompatibilities since
|
||||||
5.5.1" below. See NEWS for more information.
|
5.5.1" below. See NEWS for more information.
|
||||||
|
|
36
Src/exec.c
36
Src/exec.c
|
@ -458,7 +458,7 @@ execcursh(Estate state, int do_exec)
|
||||||
|
|
||||||
/* execve after handling $_ and #! */
|
/* execve after handling $_ and #! */
|
||||||
|
|
||||||
#define POUNDBANGLIMIT 64
|
#define POUNDBANGLIMIT 128
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static int
|
static int
|
||||||
|
@ -499,18 +499,20 @@ zexecve(char *pth, char **argv, char **newenvp)
|
||||||
if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) {
|
if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) {
|
||||||
argv0 = *argv;
|
argv0 = *argv;
|
||||||
*argv = pth;
|
*argv = pth;
|
||||||
execvebuf[0] = '\0';
|
memset(execvebuf, '\0', POUNDBANGLIMIT + 1);
|
||||||
ct = read(fd, execvebuf, POUNDBANGLIMIT);
|
ct = read(fd, execvebuf, POUNDBANGLIMIT);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (ct >= 0) {
|
if (ct >= 0) {
|
||||||
if (execvebuf[0] == '#') {
|
if (ct >= 2 && execvebuf[0] == '#' && execvebuf[1] == '!') {
|
||||||
if (execvebuf[1] == '!') {
|
for (t0 = 0; t0 != ct; t0++)
|
||||||
for (t0 = 0; t0 != ct; t0++)
|
if (execvebuf[t0] == '\n')
|
||||||
if (execvebuf[t0] == '\n')
|
break;
|
||||||
break;
|
if (t0 == ct)
|
||||||
|
zerr("%s: bad interpreter: %s: %e", pth,
|
||||||
|
execvebuf + 2, eno);
|
||||||
|
else {
|
||||||
while (inblank(execvebuf[t0]))
|
while (inblank(execvebuf[t0]))
|
||||||
execvebuf[t0--] = '\0';
|
execvebuf[t0--] = '\0';
|
||||||
execvebuf[POUNDBANGLIMIT] = '\0';
|
|
||||||
for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
|
for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
|
||||||
for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
|
for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
|
||||||
if (eno == ENOENT) {
|
if (eno == ENOENT) {
|
||||||
|
@ -519,10 +521,16 @@ zexecve(char *pth, char **argv, char **newenvp)
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
if (*ptr2 != '/' &&
|
if (*ptr2 != '/' &&
|
||||||
(pprog = pathprog(ptr2, NULL))) {
|
(pprog = pathprog(ptr2, NULL))) {
|
||||||
argv[-2] = ptr2;
|
if (ptr == execvebuf + t0 + 1) {
|
||||||
argv[-1] = ptr + 1;
|
argv[-1] = ptr2;
|
||||||
winch_unblock();
|
winch_unblock();
|
||||||
execve(pprog, argv - 2, newenvp);
|
execve(pprog, argv - 1, newenvp);
|
||||||
|
} else {
|
||||||
|
argv[-2] = ptr2;
|
||||||
|
argv[-1] = ptr + 1;
|
||||||
|
winch_unblock();
|
||||||
|
execve(pprog, argv - 2, newenvp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
zerr("%s: bad interpreter: %s: %e", pth, ptr2,
|
zerr("%s: bad interpreter: %s: %e", pth, ptr2,
|
||||||
eno);
|
eno);
|
||||||
|
@ -537,10 +545,6 @@ zexecve(char *pth, char **argv, char **newenvp)
|
||||||
winch_unblock();
|
winch_unblock();
|
||||||
execve(ptr2, argv - 1, newenvp);
|
execve(ptr2, argv - 1, newenvp);
|
||||||
}
|
}
|
||||||
} else if (eno == ENOEXEC) {
|
|
||||||
argv[-1] = "sh";
|
|
||||||
winch_unblock();
|
|
||||||
execve("/bin/sh", argv - 1, newenvp);
|
|
||||||
}
|
}
|
||||||
} else if (eno == ENOEXEC) {
|
} else if (eno == ENOEXEC) {
|
||||||
for (t0 = 0; t0 != ct; t0++)
|
for (t0 = 0; t0 != ct; t0++)
|
||||||
|
|
|
@ -12,7 +12,14 @@
|
||||||
|
|
||||||
print '#!/bin/sh\necho This is dir2' >dir2/tstcmd
|
print '#!/bin/sh\necho This is dir2' >dir2/tstcmd
|
||||||
|
|
||||||
|
print -n '#!sh\necho This is slashless' >tstcmd-slashless
|
||||||
|
print -n '#!echo foo\necho This is arg' >tstcmd-arg
|
||||||
|
print '#!xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnyyy' >tstcmd-interp-too-long
|
||||||
|
print '#!/bin/sh\necho should not execute; exit 1' >xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn
|
||||||
|
|
||||||
chmod 755 tstcmd dir1/tstcmd dir2/tstcmd
|
chmod 755 tstcmd dir1/tstcmd dir2/tstcmd
|
||||||
|
chmod 755 tstcmd-slashless tstcmd-arg tstcmd-interp-too-long
|
||||||
|
chmod 755 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn
|
||||||
|
|
||||||
%test
|
%test
|
||||||
./tstcmd
|
./tstcmd
|
||||||
|
@ -33,6 +40,21 @@
|
||||||
0:path (2)
|
0:path (2)
|
||||||
>This is top
|
>This is top
|
||||||
|
|
||||||
|
PATH=/bin:${ZTST_testdir}/command.tmp/ tstcmd-slashless
|
||||||
|
0:path (3)
|
||||||
|
>This is slashless
|
||||||
|
|
||||||
|
PATH=/bin:${ZTST_testdir}/command.tmp tstcmd-arg
|
||||||
|
0:path (4)
|
||||||
|
*>foo */command.tmp/tstcmd-arg
|
||||||
|
|
||||||
|
path=(/bin ${ZTST_testdir}/command.tmp/)
|
||||||
|
tstcmd-interp-too-long 2>&1; echo "status $?"
|
||||||
|
path=($storepath)
|
||||||
|
0:path (5)
|
||||||
|
*>*tstcmd-interp-too-long: bad interpreter: x*xn: no such file or directory
|
||||||
|
>status 127
|
||||||
|
|
||||||
functst() { print $# arguments:; print -l $*; }
|
functst() { print $# arguments:; print -l $*; }
|
||||||
functst "Eines Morgens" "als Gregor Samsa"
|
functst "Eines Morgens" "als Gregor Samsa"
|
||||||
functst ""
|
functst ""
|
||||||
|
|
Loading…
Reference in a new issue