Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145171062
D15468.id43182.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D15468.id43182.diff
View Options
Index: sys/compat/cloudabi32/cloudabi32_module.c
===================================================================
--- sys/compat/cloudabi32/cloudabi32_module.c
+++ sys/compat/cloudabi32/cloudabi32_module.c
@@ -54,7 +54,7 @@
/* Copy out program arguments. */
args = imgp->args;
- len = args->begin_envv - args->begin_argv;
+ len = exec_args_get_begin_envv(args) - args->begin_argv;
begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t));
copyout(args->begin_argv, (void *)begin, len);
return ((register_t *)begin);
@@ -109,7 +109,8 @@
* exec_copyin_data_fds(). Undo this by reducing the length.
*/
args = (Elf32_Auxargs *)imgp->auxargs;
- argdatalen = imgp->args->begin_envv - imgp->args->begin_argv;
+ argdatalen = exec_args_get_begin_envv(imgp->args) -
+ imgp->args->begin_argv;
if (argdatalen > 0)
--argdatalen;
Index: sys/compat/cloudabi64/cloudabi64_module.c
===================================================================
--- sys/compat/cloudabi64/cloudabi64_module.c
+++ sys/compat/cloudabi64/cloudabi64_module.c
@@ -54,7 +54,7 @@
/* Copy out program arguments. */
args = imgp->args;
- len = args->begin_envv - args->begin_argv;
+ len = exec_args_get_begin_envv(args) - args->begin_argv;
begin = rounddown2(imgp->sysent->sv_usrstack - len, sizeof(register_t));
copyout(args->begin_argv, (void *)begin, len);
return ((register_t *)begin);
@@ -109,7 +109,8 @@
* exec_copyin_data_fds(). Undo this by reducing the length.
*/
args = (Elf64_Auxargs *)imgp->auxargs;
- argdatalen = imgp->args->begin_envv - imgp->args->begin_argv;
+ argdatalen = exec_args_get_begin_envv(imgp->args) -
+ imgp->args->begin_argv;
if (argdatalen > 0)
--argdatalen;
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -337,7 +337,6 @@
{
char *argp, *envp;
u_int32_t *p32, arg;
- size_t length;
int error;
bzero(args, sizeof(*args));
@@ -355,19 +354,9 @@
/*
* Copy the file name.
*/
- if (fname != NULL) {
- args->fname = args->buf;
- error = (segflg == UIO_SYSSPACE) ?
- copystr(fname, args->fname, PATH_MAX, &length) :
- copyinstr(fname, args->fname, PATH_MAX, &length);
- if (error != 0)
- goto err_exit;
- } else
- length = 0;
-
- args->begin_argv = args->buf + length;
- args->endp = args->begin_argv;
- args->stringspace = ARG_MAX;
+ error = exec_args_add_fname(args, fname, segflg);
+ if (error != 0)
+ goto err_exit;
/*
* extract arguments first
@@ -380,19 +369,12 @@
if (arg == 0)
break;
argp = PTRIN(arg);
- error = copyinstr(argp, args->endp, args->stringspace, &length);
- if (error) {
- if (error == ENAMETOOLONG)
- error = E2BIG;
+ error = exec_args_add_arg(args, (void *)argp,
+ UIO_USERSPACE);
+ if (error != 0)
goto err_exit;
- }
- args->stringspace -= length;
- args->endp += length;
- args->argc++;
}
- args->begin_envv = args->endp;
-
/*
* extract environment strings
*/
@@ -405,16 +387,10 @@
if (arg == 0)
break;
envp = PTRIN(arg);
- error = copyinstr(envp, args->endp, args->stringspace,
- &length);
- if (error) {
- if (error == ENAMETOOLONG)
- error = E2BIG;
+ error = exec_args_add_env(args, (void *)envp,
+ UIO_USERSPACE);
+ if (error != 0)
goto err_exit;
- }
- args->stringspace -= length;
- args->endp += length;
- args->envc++;
}
}
Index: sys/kern/imgact_binmisc.c
===================================================================
--- sys/kern/imgact_binmisc.c
+++ sys/kern/imgact_binmisc.c
@@ -649,22 +649,13 @@
s++;
}
- /* Check to make sure we won't overrun the stringspace. */
- if (offset > imgp->args->stringspace) {
+ /* Make room for the interpreter */
+ error = exec_args_adjust_args(imgp->args, 0, offset);
+ if (error != 0) {
sx_sunlock(&interp_list_sx);
- error = E2BIG;
goto done;
}
- /* Make room for the interpreter */
- bcopy(imgp->args->begin_argv, imgp->args->begin_argv + offset,
- imgp->args->endp - imgp->args->begin_argv);
-
- /* Adjust everything by the offset. */
- imgp->args->begin_envv += offset;
- imgp->args->endp += offset;
- imgp->args->stringspace -= offset;
-
/* Add the new argument(s) in the count. */
imgp->args->argc += ibe->ibe_interp_argcnt;
Index: sys/kern/imgact_shell.c
===================================================================
--- sys/kern/imgact_shell.c
+++ sys/kern/imgact_shell.c
@@ -196,17 +196,18 @@
length = (imgp->args->argc == 0) ? 0 :
strlen(imgp->args->begin_argv) + 1; /* bytes to delete */
- if (offset > imgp->args->stringspace + length) {
+ error = exec_args_adjust_args(imgp->args, length, offset);
+ if (error != 0) {
if (sname != NULL)
sbuf_delete(sname);
- return (E2BIG);
+ return (error);
}
bcopy(imgp->args->begin_argv + length, imgp->args->begin_argv + offset,
imgp->args->endp - (imgp->args->begin_argv + length));
offset -= length; /* calculate actual adjustment */
- imgp->args->begin_envv += offset;
+ imgp->args->_begin_envv += offset;
imgp->args->endp += offset;
imgp->args->stringspace -= offset;
Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -345,9 +345,9 @@
{
AUDIT_ARG_ARGV(args->begin_argv, args->argc,
- args->begin_envv - args->begin_argv);
- AUDIT_ARG_ENVV(args->begin_envv, args->envc,
- args->endp - args->begin_envv);
+ exec_args_get_begin_envv(args) - args->begin_argv);
+ AUDIT_ARG_ENVV(exec_args_get_begin_envv(args), args->envc,
+ args->endp - exec_args_get_begin_envv(args));
return (do_execve(td, args, mac_p));
}
@@ -713,7 +713,7 @@
/*
* Malloc things before we need locks.
*/
- i = imgp->args->begin_envv - imgp->args->begin_argv;
+ i = exec_args_get_begin_envv(imgp->args) - imgp->args->begin_argv;
/* Cache arguments if they fit inside our allowance */
if (ps_arg_cache_limit >= i + sizeof(struct pargs)) {
newargs = pargs_alloc(i);
@@ -1170,7 +1170,6 @@
{
u_long argp, envp;
int error;
- size_t length;
bzero(args, sizeof(*args));
if (argv == NULL)
@@ -1187,19 +1186,9 @@
/*
* Copy the file name.
*/
- if (fname != NULL) {
- args->fname = args->buf;
- error = (segflg == UIO_SYSSPACE) ?
- copystr(fname, args->fname, PATH_MAX, &length) :
- copyinstr(fname, args->fname, PATH_MAX, &length);
- if (error != 0)
- goto err_exit;
- } else
- length = 0;
-
- args->begin_argv = args->buf + length;
- args->endp = args->begin_argv;
- args->stringspace = ARG_MAX;
+ error = exec_args_add_fname(args, fname, segflg);
+ if (error != 0)
+ goto err_exit;
/*
* extract arguments first
@@ -1212,20 +1201,12 @@
}
if (argp == 0)
break;
- error = copyinstr((void *)(uintptr_t)argp, args->endp,
- args->stringspace, &length);
- if (error != 0) {
- if (error == ENAMETOOLONG)
- error = E2BIG;
+ error = exec_args_add_arg(args, (void *)argp,
+ UIO_USERSPACE);
+ if (error != 0)
goto err_exit;
- }
- args->stringspace -= length;
- args->endp += length;
- args->argc++;
}
- args->begin_envv = args->endp;
-
/*
* extract environment strings
*/
@@ -1238,16 +1219,10 @@
}
if (envp == 0)
break;
- error = copyinstr((void *)(uintptr_t)envp,
- args->endp, args->stringspace, &length);
- if (error != 0) {
- if (error == ENAMETOOLONG)
- error = E2BIG;
+ error = exec_args_add_env(args, (void *)envp,
+ UIO_USERSPACE);
+ if (error != 0)
goto err_exit;
- }
- args->stringspace -= length;
- args->endp += length;
- args->envc++;
}
}
@@ -1302,8 +1277,6 @@
/* No argument buffer provided. */
args->endp = args->begin_argv;
}
- /* There are no environment variables. */
- args->begin_envv = args->endp;
/* Create new file descriptor table. */
kfds = malloc(fdslen * sizeof(int), M_TEMP, M_WAITOK);
@@ -1459,6 +1432,122 @@
fdescfree_remapped(args->fdp);
}
+/*
+ * A set to functions to fill struct image args.
+ *
+ * NOTE: exec_args_add_fname() must be called (possiably with a NULL
+ * fname) before the other functions. All exec_args_add_arg() calls must
+ * be made before any exec_args_add_env() calls. exec_args_adjust_args()
+ * may be called any time after exec_args_add_fname().
+ *
+ * exec_args_add_fname() - install path to be executed
+ * exec_args_add_arg() - append an argument string
+ * exec_args_add_env() - append an env string
+ * exec_args_adjust_args() - adjust location of the argument list to
+ * allow new arguments to be prepended
+ */
+int
+exec_args_add_fname(struct image_args *args, char *fname,
+ enum uio_seg segflg)
+{
+ int error;
+ size_t length;
+
+ KASSERT(args->fname == NULL, ("fname already appended"));
+ KASSERT(args->endp == NULL, ("already appending to args"));
+
+ if (fname != NULL) {
+ args->fname = args->buf;
+ error = (segflg == UIO_SYSSPACE) ?
+ copystr(fname, args->fname, PATH_MAX, &length) :
+ copyinstr(fname, args->fname, PATH_MAX, &length);
+ if (error != 0)
+ return (error == ENAMETOOLONG ? E2BIG : error);
+ } else
+ length = 0;
+
+ /* Set up for _arg_*()/_env_*() */
+ args->endp = args->buf + length;
+ /* begin_argv must be set and kept updated */
+ args->begin_argv = args->endp;
+ /* Actually (exec_map_entry_size - length) which is >= ARG_MAX */
+ args->stringspace = ARG_MAX;
+
+ return (0);
+}
+
+static int
+exec_args_add_str(struct image_args *args, char *str, enum uio_seg segflg,
+ int *countp)
+{
+ int error;
+ size_t length;
+
+ KASSERT(args->endp != NULL, ("endp not initialized"));
+ KASSERT(args->begin_argv != NULL, ("begin_argp not initialized"));
+
+ error = (segflg == UIO_SYSSPACE) ?
+ copystr(str, args->endp, args->stringspace, &length) :
+ copyinstr(str, args->endp, args->stringspace, &length);
+ if (error != 0)
+ return (error == ENAMETOOLONG ? E2BIG : error);
+ args->stringspace -= length;
+ args->endp += length;
+ (*countp)++;
+
+ return (0);
+}
+
+int
+exec_args_add_arg(struct image_args *args, char *argp, enum uio_seg segflg)
+{
+
+ KASSERT(args->envc == 0, ("appending args after env"));
+
+ return (exec_args_add_str(args, argp, segflg, &args->argc));
+}
+
+int
+exec_args_add_env(struct image_args *args, char *envp, enum uio_seg segflg)
+{
+
+ if (args->envc == 0)
+ args->_begin_envv = args->endp;
+
+ return (exec_args_add_str(args, envp, segflg, &args->envc));
+}
+
+int
+exec_args_adjust_args(struct image_args *args, size_t consume, ssize_t extend)
+{
+ ssize_t offset;
+
+ KASSERT(args->endp != NULL, ("endp not initialized"));
+ KASSERT(args->begin_argv != NULL, ("begin_argp not initialized"));
+
+ offset = extend - consume;
+ if (args->stringspace < offset)
+ return (E2BIG);
+ memmove(args->begin_argv + extend, args->begin_argv + consume,
+ args->endp - args->begin_argv + consume);
+ if (args->envc > 0)
+ args->_begin_envv += offset;
+ args->endp += offset;
+ args->stringspace -= offset;
+ return (0);
+}
+
+char *
+exec_args_get_begin_envv(struct image_args *args)
+{
+
+ KASSERT(args->endp != NULL, ("endp not initialized"));
+
+ if (args->envc > 0)
+ return (args->_begin_envv);
+ return (args->endp);
+}
+
/*
* Copy strings out to the new process address space, constructing new arg
* and env vector tables. Return a pointer to the base so that it can be used
Index: sys/sys/imgact.h
===================================================================
--- sys/sys/imgact.h
+++ sys/sys/imgact.h
@@ -46,7 +46,7 @@
char *buf; /* pointer to string buffer */
void *bufkva; /* cookie for string buffer KVA */
char *begin_argv; /* beginning of argv in buf */
- char *begin_envv; /* beginning of envv in buf */
+ char *_begin_envv; /* beginning of envv in buf */
char *endp; /* current `end' pointer of arg & env strings */
char *fname; /* pointer to filename of executable (system space) */
char *fname_buf; /* pointer to optional malloc(M_TEMP) buffer */
@@ -96,6 +96,15 @@
struct vmspace;
int exec_alloc_args(struct image_args *);
+int exec_args_add_arg(struct image_args *args, char *argp,
+ enum uio_seg segflg);
+int exec_args_add_env(struct image_args *args, char *envp,
+ enum uio_seg segflg);
+int exec_args_add_fname(struct image_args *args, char *fname,
+ enum uio_seg segflg);
+int exec_args_adjust_args(struct image_args *args, size_t consume,
+ ssize_t extend);
+char *exec_args_get_begin_envv(struct image_args *args);
int exec_check_permissions(struct image_params *);
register_t *exec_copyout_strings(struct image_params *);
void exec_free_args(struct image_args *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Feb 17, 5:47 PM (10 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28819768
Default Alt Text
D15468.id43182.diff (12 KB)
Attached To
Mode
D15468: Add helper functions to copy strings into struct image_args.
Attached
Detach File
Event Timeline
Log In to Comment