diff options
author | sobomax <sobomax@FreeBSD.org> | 2005-02-25 10:17:53 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2005-02-25 10:17:53 +0000 |
commit | 71f43f57517d3e377d334aa02c145d44c25d58b8 (patch) | |
tree | ee8d6ebe6471d7a1e93e1fed6816a1aca03bd200 /sys/kern/imgact_shell.c | |
parent | a5adba4746c343efa631d62bf8bcdda38c76f2fe (diff) | |
download | FreeBSD-src-71f43f57517d3e377d334aa02c145d44c25d58b8.zip FreeBSD-src-71f43f57517d3e377d334aa02c145d44c25d58b8.tar.gz |
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>
Diffstat (limited to 'sys/kern/imgact_shell.c')
-rw-r--r-- | sys/kern/imgact_shell.c | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/sys/kern/imgact_shell.c b/sys/kern/imgact_shell.c index 9604f41..04df003 100644 --- a/sys/kern/imgact_shell.c +++ b/sys/kern/imgact_shell.c @@ -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) @@ -67,13 +70,25 @@ 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 * line into the argument string. */ 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++; } |