Maxim Pugachev
2015-12-12 21:28:00 UTC
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:
/*
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:
/*