o Replace two while {} do loops with more appropriate do {} while loops. This
doesn't change functionality, but makes code more logical. Obtained from: DrafonFlyBSD o Use VOP_GETATTR() to obtain actual size of file and parse no more than that. Previously, we parsed MAXSHELLCMDLEN characters regardless of the actual file size. This makes the following working: $ printf '#!/bin/echo' > /tmp/test.sh $ chmod 755 /tmp/test.sh $ /tmp/test.sh Previously, attempts to execve() that shell script has been failing with bogus ENAMETOOLONG. PR: kern/64196 Submitted by: Magnus B.ckstr.m <b@etek.chalmers.se>
This commit is contained in:
parent
39aeaa0eb5
commit
6916a1da50
@ -28,6 +28,8 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/exec.h>
|
||||
@ -51,7 +53,8 @@ exec_shell_imgact(imgp)
|
||||
const char *image_header = imgp->image_header;
|
||||
const char *ihp;
|
||||
int error, offset;
|
||||
size_t length;
|
||||
size_t length, clength;
|
||||
struct vattr vattr;
|
||||
|
||||
/* a shell script? */
|
||||
if (((const short *) image_header)[0] != SHELLMAGIC)
|
||||
@ -66,6 +69,18 @@ exec_shell_imgact(imgp)
|
||||
|
||||
imgp->interpreted = 1;
|
||||
|
||||
/*
|
||||
* At this point we have the first page of the file mapped.
|
||||
* However, we don't know how far into the page the contents are
|
||||
* valid -- the actual file might be much shorter than the page.
|
||||
* So find out the file size.
|
||||
*/
|
||||
error = VOP_GETATTR(imgp->vp, &vattr, imgp->proc->p_ucred, curthread);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
clength = (vattr.va_size > MAXSHELLCMDLEN) ?
|
||||
MAXSHELLCMDLEN : vattr.va_size;
|
||||
/*
|
||||
* Figure out the number of bytes that need to be reserved in the
|
||||
* argument string to copy the contents of the interpreter's command
|
||||
@ -73,7 +88,7 @@ exec_shell_imgact(imgp)
|
||||
*/
|
||||
ihp = &image_header[2];
|
||||
offset = 0;
|
||||
while (ihp < &image_header[MAXSHELLCMDLEN]) {
|
||||
while (ihp < &image_header[clength]) {
|
||||
/* Skip any whitespace */
|
||||
if ((*ihp == ' ') || (*ihp == '\t')) {
|
||||
ihp++;
|
||||
@ -85,12 +100,12 @@ exec_shell_imgact(imgp)
|
||||
break;
|
||||
|
||||
/* Found a token */
|
||||
while ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') &&
|
||||
(*ihp != '#') && (*ihp != '\0') &&
|
||||
(ihp < &image_header[MAXSHELLCMDLEN])) {
|
||||
do {
|
||||
offset++;
|
||||
ihp++;
|
||||
}
|
||||
} while ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') &&
|
||||
(*ihp != '#') && (*ihp != '\0') &&
|
||||
(ihp < &image_header[clength]));
|
||||
/* Include terminating nulls in the offset */
|
||||
offset++;
|
||||
}
|
||||
@ -100,7 +115,7 @@ exec_shell_imgact(imgp)
|
||||
return (ENOEXEC);
|
||||
|
||||
/* Check that we aren't too big */
|
||||
if (offset > MAXSHELLCMDLEN)
|
||||
if (ihp == &image_header[MAXSHELLCMDLEN])
|
||||
return (ENAMETOOLONG);
|
||||
|
||||
/*
|
||||
@ -139,7 +154,7 @@ exec_shell_imgact(imgp)
|
||||
*/
|
||||
ihp = &image_header[2];
|
||||
offset = 0;
|
||||
while (ihp < &image_header[MAXSHELLCMDLEN]) {
|
||||
while (ihp < &image_header[clength]) {
|
||||
/* Skip whitespace */
|
||||
if ((*ihp == ' ') || (*ihp == '\t')) {
|
||||
ihp++;
|
||||
@ -151,11 +166,11 @@ exec_shell_imgact(imgp)
|
||||
break;
|
||||
|
||||
/* Found a token, copy it */
|
||||
while ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') &&
|
||||
(*ihp != '#') && (*ihp != '\0') &&
|
||||
(ihp < &image_header[MAXSHELLCMDLEN])) {
|
||||
do {
|
||||
imgp->args->begin_argv[offset++] = *ihp++;
|
||||
}
|
||||
} while ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') &&
|
||||
(*ihp != '#') && (*ihp != '\0') &&
|
||||
(ihp < &image_header[MAXSHELLCMDLEN]));
|
||||
imgp->args->begin_argv[offset++] = '\0';
|
||||
imgp->args->argc++;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user