Hi, In a case when the shell name is not specified (i.e. just "#!" without a path), don't run the heavy logic that checks shell, simply return ENOENT.
Also, as a tiny improvement: avoid a loop when calculating shell's args length. Index: sys/kern/exec_script.c =================================================================== RCS file: /cvs/src/sys/kern/exec_script.c,v retrieving revision 1.36 diff -u -p -r1.36 exec_script.c --- sys/kern/exec_script.c 10 Sep 2015 18:10:35 -0000 1.36 +++ sys/kern/exec_script.c 12 Dec 2015 21:18:22 -0000 @@ -69,7 +69,7 @@ exec_script_makecmds(struct proc *p, str { int error, hdrlinelen, shellnamelen, shellarglen; char *hdrstr = epp->ep_hdr; - char *cp, *shellname, *shellarg, *oldpnbuf; + char *cp, *endcp, *shellname, *shellarg, *oldpnbuf; char **shellargp = NULL, **tmpsap; struct vnode *scriptvp; uid_t script_uid = -1; @@ -103,6 +103,7 @@ exec_script_makecmds(struct proc *p, str for (cp = hdrstr + EXEC_SCRIPT_MAGICLEN; cp < hdrstr + hdrlinelen; cp++) { if (*cp == '\n') { + endcp = cp; *cp = '\0'; break; } @@ -119,21 +120,23 @@ exec_script_makecmds(struct proc *p, str cp++) ; + /* return error when the shell name is not specified */ + if (cp == endcp) + return ENOENT; + /* collect the shell name; remember its length for later */ shellname = cp; shellnamelen = 0; - if (*cp == '\0') - goto check_shell; for ( /* cp = cp */ ; *cp != '\0' && *cp != ' ' && *cp != '\t'; cp++) shellnamelen++; - if (*cp == '\0') + if (cp == endcp) goto check_shell; *cp++ = '\0'; /* skip spaces before any argument */ for ( /* cp = cp */ ; *cp == ' ' || *cp == '\t'; cp++) ; - if (*cp == '\0') + if (cp == endcp) goto check_shell; /* @@ -142,9 +145,7 @@ exec_script_makecmds(struct proc *p, str * behaviour. */ shellarg = cp; - for ( /* cp = cp */ ; *cp != '\0'; cp++) - shellarglen++; - *cp++ = '\0'; + shellarglen = endcp - cp; check_shell: /*