summaryrefslogtreecommitdiffstats
path: root/sys/kern/imgact_shell.c
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2005-02-25 10:17:53 +0000
committersobomax <sobomax@FreeBSD.org>2005-02-25 10:17:53 +0000
commit71f43f57517d3e377d334aa02c145d44c25d58b8 (patch)
treeee8d6ebe6471d7a1e93e1fed6816a1aca03bd200 /sys/kern/imgact_shell.c
parenta5adba4746c343efa631d62bf8bcdda38c76f2fe (diff)
downloadFreeBSD-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.c39
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++;
}
OpenPOWER on IntegriCloud