1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-05-13 02:56:18 +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:
Anthony Sottile 2018-09-03 14:39:25 +00:00 committed by Daniel Shahaf
parent baef71ccfc
commit 1c4c7b6a4d
No known key found for this signature in database
GPG Key ID: DB27E997429AF20C
6 changed files with 72 additions and 20 deletions

View File

@ -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>
* 43367: Makefile.in: Add maintainer targets 'tarxz-src' and

View File

@ -306,7 +306,7 @@ sect(On what machines will it run?)
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.
A beta of the next version is sometimes available. Development of zsh is

21
NEWS
View File

@ -4,6 +4,27 @@ CHANGES FROM PREVIOUS VERSIONS OF ZSH
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
----------------------------------

6
README
View File

@ -5,9 +5,9 @@ THE Z SHELL (ZSH)
Version
-------
This is version 5.5.1-test-2 of the shell. This is a test release. There
are some significant bug fixes and a few user visible additions since
5.5.1. All zsh installations are encouraged to upgrade.
This is version 5.6 of the shell. This is a security and feature release.
There are some significant bug fixes and a few user visible additions since
5.5.1. All zsh installations are encouraged to upgrade as soon as possible.
Note in particular the changes highlighted under "Incompatibilities since
5.5.1" below. See NEWS for more information.

View File

@ -458,7 +458,7 @@ execcursh(Estate state, int do_exec)
/* execve after handling $_ and #! */
#define POUNDBANGLIMIT 64
#define POUNDBANGLIMIT 128
/**/
static int
@ -499,18 +499,20 @@ zexecve(char *pth, char **argv, char **newenvp)
if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) {
argv0 = *argv;
*argv = pth;
execvebuf[0] = '\0';
memset(execvebuf, '\0', POUNDBANGLIMIT + 1);
ct = read(fd, execvebuf, POUNDBANGLIMIT);
close(fd);
if (ct >= 0) {
if (execvebuf[0] == '#') {
if (execvebuf[1] == '!') {
for (t0 = 0; t0 != ct; t0++)
if (execvebuf[t0] == '\n')
break;
if (ct >= 2 && execvebuf[0] == '#' && execvebuf[1] == '!') {
for (t0 = 0; t0 != ct; t0++)
if (execvebuf[t0] == '\n')
break;
if (t0 == ct)
zerr("%s: bad interpreter: %s: %e", pth,
execvebuf + 2, eno);
else {
while (inblank(execvebuf[t0]))
execvebuf[t0--] = '\0';
execvebuf[POUNDBANGLIMIT] = '\0';
for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
if (eno == ENOENT) {
@ -519,10 +521,16 @@ zexecve(char *pth, char **argv, char **newenvp)
*ptr = '\0';
if (*ptr2 != '/' &&
(pprog = pathprog(ptr2, NULL))) {
argv[-2] = ptr2;
argv[-1] = ptr + 1;
winch_unblock();
execve(pprog, argv - 2, newenvp);
if (ptr == execvebuf + t0 + 1) {
argv[-1] = ptr2;
winch_unblock();
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,
eno);
@ -537,10 +545,6 @@ zexecve(char *pth, char **argv, char **newenvp)
winch_unblock();
execve(ptr2, argv - 1, newenvp);
}
} else if (eno == ENOEXEC) {
argv[-1] = "sh";
winch_unblock();
execve("/bin/sh", argv - 1, newenvp);
}
} else if (eno == ENOEXEC) {
for (t0 = 0; t0 != ct; t0++)

View File

@ -12,7 +12,14 @@
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-slashless tstcmd-arg tstcmd-interp-too-long
chmod 755 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxn
%test
./tstcmd
@ -33,6 +40,21 @@
0:path (2)
>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 "Eines Morgens" "als Gregor Samsa"
functst ""