From 1c4c7b6a4d17294df028322b70c53803a402233d Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 3 Sep 2018 14:39:25 +0000 Subject: 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. --- Src/exec.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'Src/exec.c') diff --git a/Src/exec.c b/Src/exec.c index 615a5086f..09ee13209 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -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++) -- cgit 1.4.1