diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Src/exec.c | 27 |
2 files changed, 29 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog index 1648ea243..c89fce748 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2021-02-16 Peter Stephenson <p.stephenson@samsung.com> + + * 47876: Justtine Tunney: Src/exec.c: Add more cases where + shell scripts can be recognised from the first line as + described by POSIX. + 2021-02-16 Lawrence Velázquez <vq@larryv.me> * 47830: Doc/Zsh/contrib.yo, README: Fix some documentation typos diff --git a/Src/exec.c b/Src/exec.c index ecad923de..2301f85ad 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -547,10 +547,29 @@ zexecve(char *pth, char **argv, char **newenvp) } } } else if (eno == ENOEXEC) { - for (t0 = 0; t0 != ct; t0++) - if (!execvebuf[t0]) - break; - if (t0 == ct) { + /* Perform binary safety check on classic shell * + * scripts (shebang wasn't introduced until UNIX * + * Seventh Edition). POSIX says we shall allow * + * execution of scripts with concatenated binary * + * and suggests checking a line exists before the * + * first NUL character with a lowercase letter or * + * expansion. This is consistent with FreeBSD sh. */ + int isbinary, hasletter; + if (!(ptr2 = memchr(execvebuf, '\0', ct))) { + isbinary = 0; + } else { + isbinary = 1; + hasletter = 0; + for (ptr = execvebuf; ptr < ptr2; ptr++) { + if (islower(*ptr) || *ptr == '$' || *ptr == '`') + hasletter = 1; + if (hasletter && *ptr == '\n') { + isbinary = 0; + break; + } + } + } + if (!isbinary) { argv[-1] = "sh"; winch_unblock(); execve("/bin/sh", argv - 1, newenvp); |