o Split out kernel part of execve(2) syscall into two parts: one that
copies arguments into the kernel space and one that operates completely in the kernel space; o use kernel-only version of execve(2) to kill another stackgap in linuxlator/i386. Obtained from: DragonFlyBSD (partially) MFC after: 2 weeks
This commit is contained in:
parent
3fcd9325ec
commit
610ecfe035
@ -97,7 +97,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
(curthread->td_proc->p_flag & P_SA) == 0,
|
||||
("unsafe elf_linux_fixup(), should be curproc"));
|
||||
args = (Elf64_Auxargs *)imgp->auxargs;
|
||||
pos = *stack_base + (imgp->argc + imgp->envc + 2);
|
||||
pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
|
||||
|
||||
if (args->trace)
|
||||
AUXARGS_ENTRY(pos, AT_DEBUG, 1);
|
||||
@ -120,7 +120,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
imgp->auxargs = NULL;
|
||||
|
||||
(*stack_base)--;
|
||||
**stack_base = (register_t)imgp->argc;
|
||||
**stack_base = (register_t)imgp->args->argc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -154,8 +154,8 @@ exec_linux_imgact_try(imgp)
|
||||
if ((error = exec_shell_imgact(imgp)) == 0) {
|
||||
char *rpath = NULL;
|
||||
|
||||
linux_emul_find(FIRST_THREAD_IN_PROC(imgp->proc), NULL,
|
||||
imgp->interpreter_name, &rpath, 0);
|
||||
linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
|
||||
imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0);
|
||||
if (rpath != imgp->interpreter_name) {
|
||||
int len = strlen(rpath) + 1;
|
||||
|
||||
|
@ -118,7 +118,7 @@ exec_osf1_imgact(struct image_params *imgp)
|
||||
osf_auxargs = malloc(sizeof(Osf_Auxargs), M_TEMP, M_WAITOK | M_ZERO);
|
||||
imgp->auxargs = osf_auxargs;
|
||||
osf_auxargs->executable = osf_auxargs->exec_path;
|
||||
path_not_saved = copyinstr(imgp->fname, osf_auxargs->executable,
|
||||
path_not_saved = copystr(imgp->args->fname, osf_auxargs->executable,
|
||||
PATH_MAX, &bytes);
|
||||
if (execp->f.f_flags & DYNAMIC_FLAG) {
|
||||
if (path_not_saved) {
|
||||
@ -172,11 +172,6 @@ exec_osf1_imgact(struct image_params *imgp)
|
||||
bsize = eap->bsize;
|
||||
|
||||
imgp->entry_addr = eap->entry;
|
||||
/* copy in arguments and/or environment from old process */
|
||||
|
||||
error = exec_extract_strings(imgp);
|
||||
if (error)
|
||||
goto bail;
|
||||
|
||||
/*
|
||||
* Destroy old process VM and create a new one (with a new stack).
|
||||
|
@ -117,15 +117,15 @@ osf1_freebsd_fixup(long **stack_base, struct image_params *imgp)
|
||||
Osf_Auxargs *args;
|
||||
|
||||
args = (Osf_Auxargs *)imgp->auxargs;
|
||||
pos = *stack_base + (imgp->argc + imgp->envc + 2);
|
||||
pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
|
||||
|
||||
arginfo = (struct ps_strings *)PS_STRINGS;
|
||||
|
||||
sz = *(imgp->proc->p_sysent->sv_szsigcode);
|
||||
destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
|
||||
roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
|
||||
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
|
||||
|
||||
destp -= imgp->stringspace;
|
||||
destp -= imgp->args->stringspace;
|
||||
|
||||
destp -= strlen(args->executable)+2;
|
||||
copyout(args->executable, destp, strlen(args->executable)+1);
|
||||
@ -143,6 +143,6 @@ osf1_freebsd_fixup(long **stack_base, struct image_params *imgp)
|
||||
free(imgp->auxargs, M_TEMP);
|
||||
imgp->auxargs = NULL;
|
||||
(*stack_base)--;
|
||||
**stack_base = (long)imgp->argc;
|
||||
**stack_base = (long)imgp->args->argc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
("unsafe elf_linux_fixup(), should be curproc"));
|
||||
base = (Elf32_Addr *)*stack_base;
|
||||
args = (Elf32_Auxargs *)imgp->auxargs;
|
||||
pos = base + (imgp->argc + imgp->envc + 2);
|
||||
pos = base + (imgp->args->argc + imgp->args->envc + 2);
|
||||
|
||||
if (args->trace)
|
||||
AUXARGS_ENTRY_32(pos, AT_DEBUG, 1);
|
||||
@ -269,7 +269,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
imgp->auxargs = NULL;
|
||||
|
||||
base--;
|
||||
suword32(base, (uint32_t)imgp->argc);
|
||||
suword32(base, (uint32_t)imgp->args->argc);
|
||||
*stack_base = (register_t *)base;
|
||||
return 0;
|
||||
}
|
||||
@ -836,7 +836,7 @@ linux_copyout_strings(struct image_params *imgp)
|
||||
arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
|
||||
sigcodesz = *(imgp->proc->p_sysent->sv_szsigcode);
|
||||
destp = (caddr_t)arginfo - sigcodesz - SPARE_USRSPACE -
|
||||
roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
|
||||
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
|
||||
|
||||
/*
|
||||
* install sigcode
|
||||
@ -861,7 +861,7 @@ linux_copyout_strings(struct image_params *imgp)
|
||||
* the arg and env vector sets,and imgp->auxarg_size is room
|
||||
* for argument of Runtime loader.
|
||||
*/
|
||||
vectp = (u_int32_t *) (destp - (imgp->argc + imgp->envc + 2 +
|
||||
vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 +
|
||||
imgp->auxarg_size) * sizeof(u_int32_t));
|
||||
|
||||
} else
|
||||
@ -870,20 +870,20 @@ linux_copyout_strings(struct image_params *imgp)
|
||||
* the arg and env vector sets
|
||||
*/
|
||||
vectp = (u_int32_t *)
|
||||
(destp - (imgp->argc + imgp->envc + 2) * sizeof(u_int32_t));
|
||||
(destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
|
||||
|
||||
/*
|
||||
* vectp also becomes our initial stack base
|
||||
*/
|
||||
stack_base = vectp;
|
||||
|
||||
stringp = imgp->stringbase;
|
||||
argc = imgp->argc;
|
||||
envc = imgp->envc;
|
||||
stringp = imgp->args->begin_argv;
|
||||
argc = imgp->args->argc;
|
||||
envc = imgp->args->envc;
|
||||
/*
|
||||
* Copy out strings - arguments and environment.
|
||||
*/
|
||||
copyout(stringp, destp, ARG_MAX - imgp->stringspace);
|
||||
copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
|
||||
|
||||
/*
|
||||
* Fill in "ps_strings" struct for ps, w, etc.
|
||||
|
@ -183,7 +183,7 @@ ia32_copyout_strings(struct image_params *imgp)
|
||||
arginfo = (struct freebsd32_ps_strings *)FREEBSD32_PS_STRINGS;
|
||||
szsigcode = *(imgp->proc->p_sysent->sv_szsigcode);
|
||||
destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
|
||||
roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
|
||||
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
|
||||
|
||||
/*
|
||||
* install sigcode
|
||||
@ -208,7 +208,7 @@ ia32_copyout_strings(struct image_params *imgp)
|
||||
* the arg and env vector sets,and imgp->auxarg_size is room
|
||||
* for argument of Runtime loader.
|
||||
*/
|
||||
vectp = (u_int32_t *) (destp - (imgp->argc + imgp->envc + 2 +
|
||||
vectp = (u_int32_t *) (destp - (imgp->args->argc + imgp->args->envc + 2 +
|
||||
imgp->auxarg_size) * sizeof(u_int32_t));
|
||||
|
||||
} else
|
||||
@ -217,20 +217,20 @@ ia32_copyout_strings(struct image_params *imgp)
|
||||
* the arg and env vector sets
|
||||
*/
|
||||
vectp = (u_int32_t *)
|
||||
(destp - (imgp->argc + imgp->envc + 2) * sizeof(u_int32_t));
|
||||
(destp - (imgp->args->argc + imgp->args->envc + 2) * sizeof(u_int32_t));
|
||||
|
||||
/*
|
||||
* vectp also becomes our initial stack base
|
||||
*/
|
||||
stack_base = vectp;
|
||||
|
||||
stringp = imgp->stringbase;
|
||||
argc = imgp->argc;
|
||||
envc = imgp->envc;
|
||||
stringp = imgp->args->begin_argv;
|
||||
argc = imgp->args->argc;
|
||||
envc = imgp->args->envc;
|
||||
/*
|
||||
* Copy out strings - arguments and environment.
|
||||
*/
|
||||
copyout(stringp, destp, ARG_MAX - imgp->stringspace);
|
||||
copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
|
||||
|
||||
/*
|
||||
* Fill in "ps_strings" struct for ps, w, etc.
|
||||
|
@ -149,7 +149,7 @@ pecoff_fixup(register_t ** stack_base, struct image_params * imgp)
|
||||
struct pecoff_imghdr *ap;
|
||||
register_t *pos;
|
||||
|
||||
pos = *stack_base + (imgp->argc + imgp->envc + 2);
|
||||
pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
|
||||
ap = (struct pecoff_imghdr *) imgp->auxargs;
|
||||
if (copyout(ap, pos, len)) {
|
||||
return 0;
|
||||
@ -157,7 +157,7 @@ pecoff_fixup(register_t ** stack_base, struct image_params * imgp)
|
||||
free(ap, M_TEMP);
|
||||
imgp->auxargs = NULL;
|
||||
(*stack_base)--;
|
||||
suword(*stack_base, (long) imgp->argc);
|
||||
suword(*stack_base, (long) imgp->args->argc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -299,8 +299,6 @@ pecoff_load_file(struct thread * td, const char *file, u_long * addr, u_long * e
|
||||
* Initialize part of the common data
|
||||
*/
|
||||
imgp->proc = td->td_proc;
|
||||
imgp->userspace_argv = NULL;
|
||||
imgp->userspace_envv = NULL;
|
||||
imgp->execlabel = NULL;
|
||||
imgp->attr = &attr;
|
||||
imgp->firstpage = NULL;
|
||||
@ -418,8 +416,6 @@ exec_pecoff_coff_prep_zmagic(struct image_params * imgp,
|
||||
wp = (void *) ((char *) ap + sizeof(struct coff_aouthdr));
|
||||
error = pecoff_read_from(FIRST_THREAD_IN_PROC(imgp->proc), imgp->vp,
|
||||
peofs + PECOFF_HDR_SIZE, (caddr_t) sh, scnsiz);
|
||||
if ((error = exec_extract_strings(imgp)) != 0)
|
||||
goto fail;
|
||||
exec_new_vmspace(imgp, &pecoff_sysvec);
|
||||
vmspace = imgp->proc->p_vmspace;
|
||||
for (i = 0; i < fp->f_nscns; i++) {
|
||||
|
@ -117,11 +117,6 @@ exec_svr4_imgact(imgp)
|
||||
|
||||
VOP_UNLOCK(imgp->vp, 0, td);
|
||||
|
||||
/* copy in arguments and/or environment from old process */
|
||||
error = exec_extract_strings(imgp);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Destroy old process VM and create a new one (with a new stack)
|
||||
*/
|
||||
|
@ -215,7 +215,7 @@ svr4_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
(curthread->td_proc->p_flag & P_SA) == 0,
|
||||
("unsafe svr4_fixup(), should be curproc"));
|
||||
args = (Elf32_Auxargs *)imgp->auxargs;
|
||||
pos = *stack_base + (imgp->argc + imgp->envc + 2);
|
||||
pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
|
||||
|
||||
if (args->trace)
|
||||
AUXARGS_ENTRY(pos, AT_DEBUG, 1);
|
||||
@ -238,7 +238,7 @@ svr4_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
imgp->auxargs = NULL;
|
||||
|
||||
(*stack_base)--;
|
||||
**stack_base = (register_t)imgp->argc;
|
||||
**stack_base = (register_t)imgp->args->argc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ static int
|
||||
ibcs2_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
{
|
||||
|
||||
return (suword(--(*stack_base), imgp->argc));
|
||||
return (suword(--(*stack_base), imgp->args->argc));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -332,11 +332,6 @@ exec_coff_imgact(imgp)
|
||||
|
||||
VOP_UNLOCK(imgp->vp, 0, td);
|
||||
|
||||
if ((error = exec_extract_strings(imgp)) != 0) {
|
||||
DPRINTF(("%s(%d): return %d\n", __FILE__, __LINE__, error));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
exec_new_vmspace(imgp, &ibcs2_svr3_sysvec);
|
||||
vmspace = imgp->proc->p_vmspace;
|
||||
|
||||
|
@ -116,11 +116,6 @@ exec_linux_imgact(struct image_params *imgp)
|
||||
|
||||
VOP_UNLOCK(imgp->vp, 0, td);
|
||||
|
||||
/* copy in arguments and/or environment from old process */
|
||||
error = exec_extract_strings(imgp);
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* Destroy old process VM and create a new one (with a new stack)
|
||||
*/
|
||||
|
@ -31,7 +31,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
@ -104,21 +106,27 @@ bsd_to_linux_sigaltstack(int bsa)
|
||||
int
|
||||
linux_execve(struct thread *td, struct linux_execve_args *args)
|
||||
{
|
||||
struct execve_args bsd;
|
||||
caddr_t sg;
|
||||
int error;
|
||||
char *newpath;
|
||||
struct image_args eargs;
|
||||
|
||||
sg = stackgap_init();
|
||||
CHECKALTEXIST(td, &sg, args->path);
|
||||
error = linux_emul_convpath(td, args->path, UIO_USERSPACE,
|
||||
&newpath, 0);
|
||||
if (newpath == NULL)
|
||||
return (error);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (ldebug(execve))
|
||||
printf(ARGS(execve, "%s"), args->path);
|
||||
printf(ARGS(execve, "%s"), newpath);
|
||||
#endif
|
||||
|
||||
bsd.fname = args->path;
|
||||
bsd.argv = args->argp;
|
||||
bsd.envv = args->envp;
|
||||
return (execve(td, &bsd));
|
||||
error = exec_copyin_args(&eargs, newpath, UIO_SYSSPACE,
|
||||
args->argp, args->envp);
|
||||
free(newpath, M_TEMP);
|
||||
if (error == 0)
|
||||
kern_execve(td, &eargs, NULL);
|
||||
exec_free_args(&eargs);
|
||||
return (error);
|
||||
}
|
||||
|
||||
struct l_ipc_kludge {
|
||||
|
@ -216,13 +216,13 @@ linux_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
register_t *argv, *envp;
|
||||
|
||||
argv = *stack_base;
|
||||
envp = *stack_base + (imgp->argc + 1);
|
||||
envp = *stack_base + (imgp->args->argc + 1);
|
||||
(*stack_base)--;
|
||||
**stack_base = (intptr_t)(void *)envp;
|
||||
(*stack_base)--;
|
||||
**stack_base = (intptr_t)(void *)argv;
|
||||
(*stack_base)--;
|
||||
**stack_base = imgp->argc;
|
||||
**stack_base = imgp->args->argc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
(curthread->td_proc->p_flag & P_SA) == 0,
|
||||
("unsafe elf_linux_fixup(), should be curproc"));
|
||||
args = (Elf32_Auxargs *)imgp->auxargs;
|
||||
pos = *stack_base + (imgp->argc + imgp->envc + 2);
|
||||
pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2);
|
||||
|
||||
if (args->trace)
|
||||
AUXARGS_ENTRY(pos, AT_DEBUG, 1);
|
||||
@ -259,7 +259,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
|
||||
imgp->auxargs = NULL;
|
||||
|
||||
(*stack_base)--;
|
||||
**stack_base = (register_t)imgp->argc;
|
||||
**stack_base = (register_t)imgp->args->argc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ aout_fixup(stack_base, imgp)
|
||||
struct image_params *imgp;
|
||||
{
|
||||
|
||||
return (suword(--(*stack_base), imgp->argc));
|
||||
return (suword(--(*stack_base), imgp->args->argc));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -187,11 +187,6 @@ exec_aout_imgact(imgp)
|
||||
}
|
||||
PROC_UNLOCK(imgp->proc);
|
||||
|
||||
/* copy in arguments and/or environment from old process */
|
||||
error = exec_extract_strings(imgp);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Destroy old process VM and create a new one (with a new stack)
|
||||
*/
|
||||
|
@ -528,8 +528,6 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
||||
* Initialize part of the common data
|
||||
*/
|
||||
imgp->proc = p;
|
||||
imgp->userspace_argv = NULL;
|
||||
imgp->userspace_envv = NULL;
|
||||
imgp->attr = attr;
|
||||
imgp->firstpage = NULL;
|
||||
imgp->image_header = NULL;
|
||||
@ -647,7 +645,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
||||
u_long text_addr = 0, data_addr = 0;
|
||||
u_long seg_size, seg_addr;
|
||||
u_long addr, entry = 0, proghdr = 0;
|
||||
int error, i;
|
||||
int error = 0, i;
|
||||
const char *interp = NULL;
|
||||
Elf_Brandinfo *brand_info;
|
||||
char *path;
|
||||
@ -706,9 +704,6 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
||||
if (interp != NULL && brand_info->interp_newpath != NULL)
|
||||
interp = brand_info->interp_newpath;
|
||||
|
||||
if ((error = exec_extract_strings(imgp)) != 0)
|
||||
goto fail;
|
||||
|
||||
exec_new_vmspace(imgp, sv);
|
||||
|
||||
vmspace = imgp->proc->p_vmspace;
|
||||
@ -879,7 +874,7 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp)
|
||||
Elf_Addr *pos;
|
||||
|
||||
base = (Elf_Addr *)*stack_base;
|
||||
pos = base + (imgp->argc + imgp->envc + 2);
|
||||
pos = base + (imgp->args->argc + imgp->args->envc + 2);
|
||||
|
||||
if (args->trace) {
|
||||
AUXARGS_ENTRY(pos, AT_DEBUG, 1);
|
||||
@ -900,7 +895,7 @@ __elfN(freebsd_fixup)(register_t **stack_base, struct image_params *imgp)
|
||||
imgp->auxargs = NULL;
|
||||
|
||||
base--;
|
||||
suword(base, (long)imgp->argc);
|
||||
suword(base, (long)imgp->args->argc);
|
||||
*stack_base = (register_t *)base;
|
||||
return (0);
|
||||
}
|
||||
|
@ -225,12 +225,6 @@ do_aout_hdr(struct imgact_gzip * gz)
|
||||
/* Find out how far we should go */
|
||||
gz->file_end = gz->file_offset + gz->a_out.a_text + gz->a_out.a_data;
|
||||
|
||||
/* copy in arguments and/or environment from old process */
|
||||
error = exec_extract_strings(gz->ip);
|
||||
if (error) {
|
||||
gz->where = __LINE__;
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
* Destroy old process VM and create a new one (with a new stack)
|
||||
*/
|
||||
|
@ -42,15 +42,15 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Shell interpreter image activator. An interpreter name beginning
|
||||
* at imgp->stringbase is the minimal successful exit requirement.
|
||||
* at imgp->args->begin_argv is the minimal successful exit requirement.
|
||||
*/
|
||||
int
|
||||
exec_shell_imgact(imgp)
|
||||
struct image_params *imgp;
|
||||
{
|
||||
const char *image_header = imgp->image_header;
|
||||
const char *ihp, *line_endp;
|
||||
char *interp;
|
||||
const char *ihp;
|
||||
int error, length, offset;
|
||||
|
||||
/* a shell script? */
|
||||
if (((const short *) image_header)[0] != SHELLMAGIC)
|
||||
@ -66,64 +66,110 @@ exec_shell_imgact(imgp)
|
||||
imgp->interpreted = 1;
|
||||
|
||||
/*
|
||||
* Copy shell name and arguments from image_header into string
|
||||
* buffer.
|
||||
* 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]) {
|
||||
/* Skip any whitespace */
|
||||
while ((*ihp == ' ') || (*ihp == '\t')) {
|
||||
ihp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* End of line? */
|
||||
if ((*ihp == '\n') || (*ihp == '#'))
|
||||
break;
|
||||
|
||||
/* Found a token */
|
||||
while ((*ihp != ' ') && (*ihp != '\t') && (*ihp != '\n') &&
|
||||
(*ihp != '#')) {
|
||||
offset++;
|
||||
ihp++;
|
||||
}
|
||||
/* Include terminating nulls in the offset */
|
||||
offset++;
|
||||
}
|
||||
|
||||
/* If the script gives a null line as the interpreter, we bail */
|
||||
if (offset == 0)
|
||||
return (ENOEXEC);
|
||||
|
||||
/* Check that we aren't too big */
|
||||
if (offset > MAXSHELLCMDLEN)
|
||||
return (ENAMETOOLONG);
|
||||
|
||||
/*
|
||||
* Find end of line; return if the line > MAXSHELLCMDLEN long.
|
||||
* The full path name of the original script file must be tagged
|
||||
* onto the end, adjust the offset to deal with it.
|
||||
*
|
||||
* The original argv[0] is being replaced, set 'length' to the number
|
||||
* of bytes being removed. So 'offset' is the number of bytes being
|
||||
* added and 'length' is the number of bytes being removed.
|
||||
*/
|
||||
for (ihp = &image_header[2]; *ihp != '\n'; ++ihp) {
|
||||
if (ihp >= &image_header[MAXSHELLCMDLEN])
|
||||
return(ENAMETOOLONG);
|
||||
}
|
||||
line_endp = ihp;
|
||||
offset += strlen(imgp->args->fname) + 1; /* add fname */
|
||||
length = (imgp->args->argc == 0) ? 0 :
|
||||
strlen(imgp->args->begin_argv) + 1; /* bytes to delete */
|
||||
|
||||
/* reset for another pass */
|
||||
if (offset - length > imgp->args->stringspace)
|
||||
return (E2BIG);
|
||||
|
||||
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->endp += offset;
|
||||
imgp->args->stringspace -= offset;
|
||||
|
||||
/*
|
||||
* If there were no arguments then we've added one, otherwise
|
||||
* decr argc remove old argv[0], incr argc for fname add, net 0
|
||||
*/
|
||||
if (imgp->args->argc == 0)
|
||||
imgp->args->argc = 1;
|
||||
|
||||
/*
|
||||
* Loop through the interpreter name yet again, copying as
|
||||
* we go.
|
||||
*/
|
||||
ihp = &image_header[2];
|
||||
|
||||
/* Skip over leading spaces - until the interpreter name */
|
||||
while ((*ihp == ' ') || (*ihp == '\t')) ihp++;
|
||||
|
||||
/* copy the interpreter name */
|
||||
interp = imgp->interpreter_name;
|
||||
while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t'))
|
||||
*interp++ = *ihp++;
|
||||
*interp = '\0';
|
||||
|
||||
/* Disallow a null interpreter filename */
|
||||
if (*imgp->interpreter_name == '\0')
|
||||
return(ENOEXEC);
|
||||
|
||||
/* reset for another pass */
|
||||
ihp = &image_header[2];
|
||||
|
||||
/* copy the interpreter name and arguments */
|
||||
while (ihp < line_endp) {
|
||||
/* Skip over leading spaces */
|
||||
while ((*ihp == ' ') || (*ihp == '\t')) ihp++;
|
||||
|
||||
if (ihp < line_endp) {
|
||||
/*
|
||||
* Copy to end of token. No need to watch stringspace
|
||||
* because this is at the front of the string buffer
|
||||
* and the maximum shell command length is tiny.
|
||||
*/
|
||||
while ((ihp < line_endp) && (*ihp != ' ') && (*ihp != '\t')) {
|
||||
*imgp->stringp++ = *ihp++;
|
||||
imgp->stringspace--;
|
||||
}
|
||||
|
||||
*imgp->stringp++ = 0;
|
||||
imgp->stringspace--;
|
||||
|
||||
imgp->argc++;
|
||||
offset = 0;
|
||||
while (ihp < &image_header[MAXSHELLCMDLEN]) {
|
||||
/* Skip whitespace */
|
||||
while ((*ihp == ' ' || *ihp == '\t')) {
|
||||
ihp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* End of line? */
|
||||
if ((*ihp == '\n') || (*ihp == '#'))
|
||||
break;
|
||||
|
||||
/* Found a token, copy it */
|
||||
while ((*ihp != ' ') && (*ihp != '\t') &&
|
||||
(*ihp != '\n') && (*ihp != '#')) {
|
||||
imgp->args->begin_argv[offset++] = *ihp++;
|
||||
}
|
||||
imgp->args->begin_argv[offset++] = '\0';
|
||||
imgp->args->argc++;
|
||||
}
|
||||
|
||||
imgp->argv0 = imgp->fname;
|
||||
/*
|
||||
* Finally, add the filename onto the end for the interpreter to
|
||||
* use and copy the interpreter's name to imgp->interpreter_name
|
||||
* for exec to use.
|
||||
*/
|
||||
error = copystr(imgp->args->fname, imgp->args->buf + offset,
|
||||
imgp->args->stringspace, &length);
|
||||
|
||||
return(0);
|
||||
if (error == 0)
|
||||
error = copystr(imgp->args->begin_argv, imgp->interpreter_name,
|
||||
MAXSHELLCMDLEN, &length);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -79,8 +79,8 @@ MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments");
|
||||
static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS);
|
||||
static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS);
|
||||
static int sysctl_kern_stackprot(SYSCTL_HANDLER_ARGS);
|
||||
static int do_execve(struct thread *td, char *fname, char **argv,
|
||||
char **envv, struct mac *mac_p);
|
||||
static int do_execve(struct thread *td, struct image_args *args,
|
||||
struct mac *mac_p);
|
||||
|
||||
/* XXX This should be vm_size_t. */
|
||||
SYSCTL_PROC(_kern, KERN_PS_STRINGS, ps_strings, CTLTYPE_ULONG|CTLFLAG_RD,
|
||||
@ -171,8 +171,18 @@ execve(td, uap)
|
||||
char **envv;
|
||||
} */ *uap;
|
||||
{
|
||||
int error;
|
||||
struct image_args args;
|
||||
|
||||
return (kern_execve(td, uap->fname, uap->argv, uap->envv, NULL));
|
||||
error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE,
|
||||
uap->argv, uap->envv);
|
||||
|
||||
if (error == 0)
|
||||
error = kern_execve(td, &args, NULL);
|
||||
|
||||
exec_free_args(&args);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
@ -197,21 +207,28 @@ __mac_execve(td, uap)
|
||||
struct mac *mac_p;
|
||||
} */ *uap;
|
||||
{
|
||||
|
||||
#ifdef MAC
|
||||
return (kern_execve(td, uap->fname, uap->argv, uap->envv,
|
||||
uap->mac_p));
|
||||
int error;
|
||||
struct image_args args;
|
||||
|
||||
error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE,
|
||||
uap->argv, uap->envv);
|
||||
|
||||
if (error == 0)
|
||||
error = kern_execve(td, &args, uap->mac_p);
|
||||
|
||||
exec_free_args(&args);
|
||||
|
||||
return (error);
|
||||
#else
|
||||
return (ENOSYS);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
kern_execve(td, fname, argv, envv, mac_p)
|
||||
kern_execve(td, args, mac_p)
|
||||
struct thread *td;
|
||||
char *fname;
|
||||
char **argv;
|
||||
char **envv;
|
||||
struct image_args *args;
|
||||
struct mac *mac_p;
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
@ -226,7 +243,7 @@ kern_execve(td, fname, argv, envv, mac_p)
|
||||
PROC_UNLOCK(p);
|
||||
}
|
||||
|
||||
error = do_execve(td, fname, argv, envv, mac_p);
|
||||
error = do_execve(td, args, mac_p);
|
||||
|
||||
if (p->p_flag & P_HADTHREADS) {
|
||||
PROC_LOCK(p);
|
||||
@ -235,7 +252,7 @@ kern_execve(td, fname, argv, envv, mac_p)
|
||||
* force other threads to suicide.
|
||||
*/
|
||||
if (error == 0)
|
||||
thread_single(SINGLE_EXIT);
|
||||
thread_single(SINGLE_EXIT);
|
||||
else
|
||||
thread_single_end();
|
||||
PROC_UNLOCK(p);
|
||||
@ -251,11 +268,9 @@ kern_execve(td, fname, argv, envv, mac_p)
|
||||
* MPSAFE
|
||||
*/
|
||||
static int
|
||||
do_execve(td, fname, argv, envv, mac_p)
|
||||
do_execve(td, args, mac_p)
|
||||
struct thread *td;
|
||||
char *fname;
|
||||
char **argv;
|
||||
char **envv;
|
||||
struct image_args *args;
|
||||
struct mac *mac_p;
|
||||
{
|
||||
struct proc *p = td->td_proc;
|
||||
@ -300,12 +315,8 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
* Initialize part of the common data
|
||||
*/
|
||||
imgp->proc = p;
|
||||
imgp->userspace_argv = argv;
|
||||
imgp->userspace_envv = envv;
|
||||
imgp->execlabel = NULL;
|
||||
imgp->attr = &attr;
|
||||
imgp->argc = imgp->envc = 0;
|
||||
imgp->argv0 = NULL;
|
||||
imgp->entry_addr = 0;
|
||||
imgp->vmspace_destroyed = 0;
|
||||
imgp->interpreted = 0;
|
||||
@ -316,6 +327,7 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
imgp->firstpage = NULL;
|
||||
imgp->ps_strings = 0;
|
||||
imgp->auxarg_size = 0;
|
||||
imgp->args = args;
|
||||
|
||||
#ifdef MAC
|
||||
error = mac_execve_enter(imgp, mac_p);
|
||||
@ -325,18 +337,6 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Allocate temporary demand zeroed space for argument and
|
||||
* environment strings
|
||||
*/
|
||||
imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX);
|
||||
if (imgp->stringbase == NULL) {
|
||||
error = ENOMEM;
|
||||
mtx_lock(&Giant);
|
||||
goto exec_fail;
|
||||
}
|
||||
imgp->stringp = imgp->stringbase;
|
||||
imgp->stringspace = ARG_MAX;
|
||||
imgp->image_header = NULL;
|
||||
|
||||
/*
|
||||
@ -345,20 +345,16 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
*/
|
||||
ndp = &nd;
|
||||
NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
|
||||
UIO_USERSPACE, fname, td);
|
||||
UIO_SYSSPACE, args->fname, td);
|
||||
|
||||
mtx_lock(&Giant);
|
||||
interpret:
|
||||
|
||||
error = namei(ndp);
|
||||
if (error) {
|
||||
kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
|
||||
ARG_MAX);
|
||||
if (error)
|
||||
goto exec_fail;
|
||||
}
|
||||
|
||||
imgp->vp = ndp->ni_vp;
|
||||
imgp->fname = fname;
|
||||
|
||||
/*
|
||||
* Check file permissions (also 'opens' file)
|
||||
@ -387,7 +383,7 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
|
||||
/*
|
||||
* If the current process has a special image activator it
|
||||
* wants to try first, call it. For example, emulating shell
|
||||
* wants to try first, call it. For example, emulating shell
|
||||
* scripts differently.
|
||||
*/
|
||||
error = -1;
|
||||
@ -460,7 +456,7 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
if (p->p_sysent->sv_fixup != NULL)
|
||||
(*p->p_sysent->sv_fixup)(&stack_base, imgp);
|
||||
else
|
||||
suword(--stack_base, imgp->argc);
|
||||
suword(--stack_base, imgp->args->argc);
|
||||
|
||||
/*
|
||||
* For security and other reasons, the file descriptor table cannot
|
||||
@ -473,7 +469,7 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
*/
|
||||
newcred = crget();
|
||||
euip = uifind(attr.va_uid);
|
||||
i = imgp->endargs - imgp->stringbase;
|
||||
i = imgp->args->begin_envv - imgp->args->begin_argv;
|
||||
if (ps_arg_cache_limit >= i + sizeof(struct pargs))
|
||||
newargs = pargs_alloc(i);
|
||||
|
||||
@ -662,7 +658,7 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
|
||||
/* Cache arguments if they fit inside our allowance */
|
||||
if (ps_arg_cache_limit >= i + sizeof(struct pargs)) {
|
||||
bcopy(imgp->stringbase, newargs->ar_args, i);
|
||||
bcopy(imgp->args->begin_argv, newargs->ar_args, i);
|
||||
p->p_args = newargs;
|
||||
newargs = NULL;
|
||||
}
|
||||
@ -718,10 +714,6 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
vput(imgp->vp);
|
||||
}
|
||||
|
||||
if (imgp->stringbase != NULL)
|
||||
kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
|
||||
ARG_MAX);
|
||||
|
||||
if (imgp->object != NULL)
|
||||
vm_object_deallocate(imgp->object);
|
||||
|
||||
@ -739,7 +731,7 @@ do_execve(td, fname, argv, envv, mac_p)
|
||||
PROC_LOCK(p);
|
||||
p->p_flag &= ~P_INEXEC;
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
|
||||
if (imgp->vmspace_destroyed) {
|
||||
/* sorry, no more process anymore. exit gracefully */
|
||||
#ifdef MAC
|
||||
@ -925,73 +917,95 @@ exec_new_vmspace(imgp, sv)
|
||||
* address space into the temporary string buffer.
|
||||
*/
|
||||
int
|
||||
exec_extract_strings(imgp)
|
||||
struct image_params *imgp;
|
||||
exec_copyin_args(struct image_args *args, char *fname,
|
||||
enum uio_seg segflg, char **argv, char **envv)
|
||||
{
|
||||
char **argv, **envv;
|
||||
char *argp, *envp;
|
||||
int error;
|
||||
size_t length;
|
||||
char *argp, *envp;
|
||||
int error;
|
||||
size_t length;
|
||||
|
||||
error = 0;
|
||||
|
||||
bzero(args, sizeof(*args));
|
||||
if (argv == NULL)
|
||||
return (EFAULT);
|
||||
/*
|
||||
* Allocate temporary demand zeroed space for argument and
|
||||
* environment strings
|
||||
*/
|
||||
args->buf = (char *) kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX);
|
||||
if (args->buf == NULL)
|
||||
return (ENOMEM);
|
||||
args->begin_argv = args->buf;
|
||||
args->endp = args->begin_argv;
|
||||
args->stringspace = ARG_MAX;
|
||||
|
||||
args->fname = args->buf + ARG_MAX;
|
||||
|
||||
/*
|
||||
* Copy the file name.
|
||||
*/
|
||||
error = (segflg == UIO_SYSSPACE) ?
|
||||
copystr(fname, args->fname, PATH_MAX, &length) :
|
||||
copyinstr(fname, args->fname, PATH_MAX, &length);
|
||||
if (error != 0) {
|
||||
if (error == ENAMETOOLONG)
|
||||
return (E2BIG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* extract arguments first
|
||||
*/
|
||||
|
||||
argv = imgp->userspace_argv;
|
||||
|
||||
if (argv) {
|
||||
argp = (caddr_t)(intptr_t)fuword(argv);
|
||||
if (argp == (caddr_t)-1)
|
||||
while ((argp = (caddr_t) (intptr_t) fuword(argv++))) {
|
||||
if (argp == (caddr_t) -1)
|
||||
return (EFAULT);
|
||||
if (argp)
|
||||
argv++;
|
||||
if (imgp->argv0)
|
||||
argp = imgp->argv0;
|
||||
if (argp) {
|
||||
do {
|
||||
if (argp == (caddr_t)-1)
|
||||
return (EFAULT);
|
||||
if ((error = copyinstr(argp, imgp->stringp,
|
||||
imgp->stringspace, &length))) {
|
||||
if (error == ENAMETOOLONG)
|
||||
return (E2BIG);
|
||||
return (error);
|
||||
}
|
||||
imgp->stringspace -= length;
|
||||
imgp->stringp += length;
|
||||
imgp->argc++;
|
||||
} while ((argp = (caddr_t)(intptr_t)fuword(argv++)));
|
||||
if ((error = copyinstr(argp, args->endp,
|
||||
args->stringspace, &length))) {
|
||||
if (error == ENAMETOOLONG)
|
||||
return (E2BIG);
|
||||
return (error);
|
||||
}
|
||||
} else
|
||||
return (EFAULT);
|
||||
args->stringspace -= length;
|
||||
args->endp += length;
|
||||
args->argc++;
|
||||
}
|
||||
|
||||
imgp->endargs = imgp->stringp;
|
||||
args->begin_envv = args->endp;
|
||||
|
||||
/*
|
||||
* extract environment strings
|
||||
*/
|
||||
|
||||
envv = imgp->userspace_envv;
|
||||
|
||||
if (envv) {
|
||||
while ((envp = (caddr_t)(intptr_t)fuword(envv++))) {
|
||||
if (envp == (caddr_t)-1)
|
||||
return (EFAULT);
|
||||
if ((error = copyinstr(envp, imgp->stringp,
|
||||
imgp->stringspace, &length))) {
|
||||
if ((error = copyinstr(envp, args->endp,
|
||||
args->stringspace, &length))) {
|
||||
if (error == ENAMETOOLONG)
|
||||
return (E2BIG);
|
||||
return (error);
|
||||
}
|
||||
imgp->stringspace -= length;
|
||||
imgp->stringp += length;
|
||||
imgp->envc++;
|
||||
args->stringspace -= length;
|
||||
args->endp += length;
|
||||
args->envc++;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
exec_free_args(struct image_args *args)
|
||||
{
|
||||
|
||||
if (args->buf) {
|
||||
kmem_free_wakeup(exec_map,
|
||||
(vm_offset_t)args->buf, PATH_MAX + ARG_MAX);
|
||||
args->buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy strings out to the new process address space, constructing
|
||||
* new arg and env vector tables. Return a pointer to the base
|
||||
@ -1019,7 +1033,7 @@ exec_copyout_strings(imgp)
|
||||
if (p->p_sysent->sv_szsigcode != NULL)
|
||||
szsigcode = *(p->p_sysent->sv_szsigcode);
|
||||
destp = (caddr_t)arginfo - szsigcode - SPARE_USRSPACE -
|
||||
roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
|
||||
roundup((ARG_MAX - imgp->args->stringspace), sizeof(char *));
|
||||
|
||||
/*
|
||||
* install sigcode
|
||||
@ -1044,30 +1058,32 @@ exec_copyout_strings(imgp)
|
||||
* the arg and env vector sets,and imgp->auxarg_size is room
|
||||
* for argument of Runtime loader.
|
||||
*/
|
||||
vectp = (char **)(destp - (imgp->argc + imgp->envc + 2 +
|
||||
imgp->auxarg_size) * sizeof(char *));
|
||||
vectp = (char **)(destp - (imgp->args->argc +
|
||||
imgp->args->envc + 2 + imgp->auxarg_size) *
|
||||
sizeof(char *));
|
||||
|
||||
} else
|
||||
} else {
|
||||
/*
|
||||
* The '+ 2' is for the null pointers at the end of each of
|
||||
* the arg and env vector sets
|
||||
*/
|
||||
vectp = (char **)(destp - (imgp->argc + imgp->envc + 2) *
|
||||
vectp = (char **)(destp - (imgp->args->argc + imgp->args->envc + 2) *
|
||||
sizeof(char *));
|
||||
}
|
||||
|
||||
/*
|
||||
* vectp also becomes our initial stack base
|
||||
*/
|
||||
stack_base = (register_t *)vectp;
|
||||
|
||||
stringp = imgp->stringbase;
|
||||
argc = imgp->argc;
|
||||
envc = imgp->envc;
|
||||
stringp = imgp->args->begin_argv;
|
||||
argc = imgp->args->argc;
|
||||
envc = imgp->args->envc;
|
||||
|
||||
/*
|
||||
* Copy out strings - arguments and environment.
|
||||
*/
|
||||
copyout(stringp, destp, ARG_MAX - imgp->stringspace);
|
||||
copyout(stringp, destp, ARG_MAX - imgp->args->stringspace);
|
||||
|
||||
/*
|
||||
* Fill in "ps_strings" struct for ps, w, etc.
|
||||
|
@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/imgact.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
@ -176,6 +177,7 @@ int
|
||||
kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap)
|
||||
{
|
||||
struct kse_execve_args args;
|
||||
struct image_args iargs;
|
||||
struct proc *p;
|
||||
struct thread *td2;
|
||||
struct kse_upcall *ku;
|
||||
@ -261,7 +263,11 @@ kse_thr_interrupt(struct thread *td, struct kse_thr_interrupt_args *uap)
|
||||
error = copyin((void *)uap->data, &args, sizeof(args));
|
||||
if (error)
|
||||
return (error);
|
||||
error = kern_execve(td, args.path, args.argv, args.envp, NULL);
|
||||
error = exec_copyin_args(&iargs, args.path, UIO_USERSPACE,
|
||||
args.argv, args.envp);
|
||||
if (error == 0)
|
||||
error = kern_execve(td, &iargs, NULL);
|
||||
exec_free_args(&iargs);
|
||||
if (error == 0) {
|
||||
PROC_LOCK(p);
|
||||
SIGSETOR(td->td_siglist, args.sigpend);
|
||||
|
@ -175,6 +175,7 @@ SUBDIR= ${_3dfx} \
|
||||
procfs \
|
||||
pseudofs \
|
||||
${_pst} \
|
||||
${_radio} \
|
||||
${_random} \
|
||||
${_ray} \
|
||||
rc \
|
||||
@ -326,6 +327,7 @@ _oltr= oltr
|
||||
_pccard= pccard
|
||||
_pcfclock= pcfclock
|
||||
_pecoff= pecoff
|
||||
#_radio= radio
|
||||
_pst= pst
|
||||
_ray= ray
|
||||
_safe= safe
|
||||
|
@ -32,32 +32,37 @@
|
||||
#ifndef _SYS_IMGACT_H_
|
||||
#define _SYS_IMGACT_H_
|
||||
|
||||
#include <sys/uio.h>
|
||||
|
||||
#define MAXSHELLCMDLEN 128
|
||||
|
||||
struct image_args {
|
||||
char *buf; /* pointer to string buffer */
|
||||
char *begin_argv; /* beginning of argv 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) */
|
||||
int stringspace; /* space left in arg & env buffer */
|
||||
int argc; /* count of argument strings */
|
||||
int envc; /* count of environment strings */
|
||||
};
|
||||
|
||||
struct image_params {
|
||||
struct proc *proc; /* our process struct */
|
||||
char **userspace_argv; /* system call argument */
|
||||
char **userspace_envv; /* system call argument */
|
||||
struct label *execlabel; /* optional exec label */
|
||||
struct vnode *vp; /* pointer to vnode of file to exec */
|
||||
struct vm_object *object; /* The vm object for this vp */
|
||||
struct vattr *attr; /* attributes of file */
|
||||
const char *image_header; /* head of file to exec */
|
||||
char *stringbase; /* base address of tmp string storage */
|
||||
char *stringp; /* current 'end' pointer of tmp strings */
|
||||
char *endargs; /* end of argv vector */
|
||||
int stringspace; /* space left in tmp string storage area */
|
||||
int argc, envc; /* count of argument and environment strings */
|
||||
char *argv0; /* Replacement for argv[0] when interpreting */
|
||||
unsigned long entry_addr; /* entry address of target executable */
|
||||
char vmspace_destroyed; /* flag - we've blown away original vm space */
|
||||
char interpreted; /* flag - this executable is interpreted */
|
||||
char interpreter_name[MAXSHELLCMDLEN]; /* name of the interpreter */
|
||||
void *auxargs; /* ELF Auxinfo structure pointer */
|
||||
struct sf_buf *firstpage; /* first page that we mapped */
|
||||
char *fname; /* pointer to filename of executable (user space) */
|
||||
unsigned long ps_strings; /* PS_STRINGS for BSD/OS binaries */
|
||||
size_t auxarg_size;
|
||||
struct image_args *args; /* system call arguments */
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
@ -66,10 +71,12 @@ struct thread;
|
||||
|
||||
int exec_check_permissions(struct image_params *);
|
||||
register_t *exec_copyout_strings(struct image_params *);
|
||||
int exec_extract_strings(struct image_params *);
|
||||
int exec_new_vmspace(struct image_params *, struct sysentvec *);
|
||||
void exec_setregs(struct thread *, u_long, u_long, u_long);
|
||||
int exec_shell_imgact(struct image_params *);
|
||||
int exec_copyin_args(struct image_args *, char *, enum uio_seg,
|
||||
char **, char **);
|
||||
void exec_free_args(struct image_args *);
|
||||
#endif
|
||||
|
||||
#endif /* !_SYS_IMGACT_H_ */
|
||||
|
@ -40,6 +40,7 @@ struct rusage;
|
||||
struct sockaddr;
|
||||
struct itimerval;
|
||||
struct msqid_ds;
|
||||
struct image_args;
|
||||
|
||||
int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg,
|
||||
u_int buflen);
|
||||
@ -52,7 +53,7 @@ int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg,
|
||||
int kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid,
|
||||
int gid);
|
||||
int kern_connect(struct thread *td, int fd, struct sockaddr *sa);
|
||||
int kern_execve(struct thread *td, char *fname, char **argv, char **envv,
|
||||
int kern_execve(struct thread *td, struct image_args *args,
|
||||
struct mac *mac_p);
|
||||
int kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg);
|
||||
int kern_futimes(struct thread *td, int fd, struct timeval *tptr,
|
||||
|
Loading…
Reference in New Issue
Block a user