summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2010-09-21 16:24:51 +0000
committerAlan Cox <alc@FreeBSD.org>2010-09-21 16:24:51 +0000
commit8f7f5a7f26ba1c1f1af672f1975d2b5fb57a051b (patch)
tree678f632332f49df72469a35d01eac0912c8bef7b
parent088acbb3128a5c807945ea8940ccffd50d575705 (diff)
Notes
-rw-r--r--lib/libc/sys/execve.210
-rw-r--r--sys/kern/imgact_shell.c28
-rw-r--r--sys/sys/param.h2
3 files changed, 23 insertions, 17 deletions
diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2
index 0559a1a614d66..991495c3c9d80 100644
--- a/lib/libc/sys/execve.2
+++ b/lib/libc/sys/execve.2
@@ -28,7 +28,7 @@
.\" @(#)execve.2 8.5 (Berkeley) 6/1/94
.\" $FreeBSD$
.\"
-.Dd April 10, 2008
+.Dd September 21, 2010
.Dt EXECVE 2
.Os
.Sh NAME
@@ -256,9 +256,11 @@ A component of the path prefix is not a directory.
.It Bq Er ENAMETOOLONG
A component of a pathname exceeded 255 characters,
or an entire path name exceeded 1023 characters.
-.It Bq Er ENAMETOOLONG
-When invoking an interpreted script, the interpreter name
-exceeds
+.It Bq Er ENOEXEC
+When invoking an interpreted script, the length of the first line,
+inclusive of the
+.Sy \&#!
+prefix and terminating newline, exceeds
.Dv MAXSHELLCMDLEN
characters.
.It Bq Er ENOENT
diff --git a/sys/kern/imgact_shell.c b/sys/kern/imgact_shell.c
index d0ef87c1e2317..0dc9299f54346 100644
--- a/sys/kern/imgact_shell.c
+++ b/sys/kern/imgact_shell.c
@@ -46,13 +46,18 @@ __FBSDID("$FreeBSD$");
/*
* At the time of this writing, MAXSHELLCMDLEN == PAGE_SIZE. This is
* significant because the caller has only mapped in one page of the
- * file we're reading. This code should be changed to know how to
- * read in the second page, but I'm not doing that just yet...
+ * file we're reading.
*/
#if MAXSHELLCMDLEN > PAGE_SIZE
#error "MAXSHELLCMDLEN is larger than a single page!"
#endif
+/*
+ * MAXSHELLCMDLEN must be at least MAXINTERP plus the size of the `#!'
+ * prefix and terminating newline.
+ */
+CTASSERT(MAXSHELLCMDLEN >= MAXINTERP + 3);
+
/**
* Shell interpreter image activator. An interpreter name beginning at
* imgp->args->begin_argv is the minimal successful exit requirement.
@@ -98,20 +103,20 @@ exec_shell_imgact(imgp)
const char *image_header = imgp->image_header;
const char *ihp, *interpb, *interpe, *maxp, *optb, *opte, *fname;
int error, offset;
- size_t length, clength;
+ size_t length;
struct vattr vattr;
struct sbuf *sname;
/* a shell script? */
- if (((const short *) image_header)[0] != SHELLMAGIC)
- return(-1);
+ if (((const short *)image_header)[0] != SHELLMAGIC)
+ return (-1);
/*
* Don't allow a shell script to be the shell for a shell
* script. :-)
*/
if (imgp->interpreted)
- return(ENOEXEC);
+ return (ENOEXEC);
imgp->interpreted = 1;
@@ -127,12 +132,9 @@ exec_shell_imgact(imgp)
/*
* Copy shell name and arguments from image_header into a string
- * buffer. Remember that the caller has mapped only the
- * first page of the file into memory.
+ * buffer.
*/
- clength = (vattr.va_size > PAGE_SIZE) ? PAGE_SIZE : vattr.va_size;
-
- maxp = &image_header[clength];
+ maxp = &image_header[MIN(vattr.va_size, MAXSHELLCMDLEN)];
ihp = &image_header[2];
/*
@@ -149,7 +151,7 @@ exec_shell_imgact(imgp)
interpe = ihp;
if (interpb == interpe)
return (ENOEXEC);
- if ((interpe - interpb) >= MAXSHELLCMDLEN)
+ if (interpe - interpb >= MAXINTERP)
return (ENAMETOOLONG);
/*
@@ -163,6 +165,8 @@ exec_shell_imgact(imgp)
while (ihp < maxp && ((*ihp != '\n') && (*ihp != '\0')))
ihp++;
opte = ihp;
+ if (opte == maxp)
+ return (ENOEXEC);
while (--ihp > optb && ((*ihp == ' ') || (*ihp == '\t')))
opte = ihp;
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 8ca03f3392bc4..63ad0088c2884 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -73,7 +73,7 @@
#include <sys/syslimits.h>
#define MAXCOMLEN 19 /* max command name remembered */
-#define MAXINTERP 32 /* max interpreter file name length */
+#define MAXINTERP PATH_MAX /* max interpreter file name length */
#define MAXLOGNAME 17 /* max login name length (incl. NUL) */
#define MAXUPRC CHILD_MAX /* max simultaneous processes */
#define NCARGS ARG_MAX /* max bytes for an exec function */