Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/kern_exec.c
Show First 20 Lines • Show All 354 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
static int | static int | ||||
do_execve(struct thread *td, struct image_args *args, struct mac *mac_p) | do_execve(struct thread *td, struct image_args *args, struct mac *mac_p) | ||||
{ | { | ||||
struct proc *p = td->td_proc; | struct proc *p = td->td_proc; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
struct ucred *oldcred; | struct ucred *oldcred; | ||||
struct uidinfo *euip = NULL; | struct uidinfo *euip = NULL; | ||||
register_t *stack_base; | uintptr_t stack_base; | ||||
struct image_params image_params, *imgp; | struct image_params image_params, *imgp; | ||||
struct vattr attr; | struct vattr attr; | ||||
int (*img_first)(struct image_params *); | int (*img_first)(struct image_params *); | ||||
struct pargs *oldargs = NULL, *newargs = NULL; | struct pargs *oldargs = NULL, *newargs = NULL; | ||||
struct sigacts *oldsigacts = NULL, *newsigacts = NULL; | struct sigacts *oldsigacts = NULL, *newsigacts = NULL; | ||||
#ifdef KTRACE | #ifdef KTRACE | ||||
struct vnode *tracevp = NULL; | struct vnode *tracevp = NULL; | ||||
struct ucred *tracecred = NULL; | struct ucred *tracecred = NULL; | ||||
▲ Show 20 Lines • Show All 491 Lines • ▼ Show 20 Lines | if (PMC_SYSTEM_SAMPLING_ACTIVE() || PMC_PROC_IS_USING_PMCS(p)) { | ||||
pe.pm_entryaddr = imgp->entry_addr; | pe.pm_entryaddr = imgp->entry_addr; | ||||
PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, (void *) &pe); | PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, (void *) &pe); | ||||
vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | ||||
} | } | ||||
#endif | #endif | ||||
/* Set values passed into the program in registers. */ | /* Set values passed into the program in registers. */ | ||||
(*p->p_sysent->sv_setregs)(td, imgp, (u_long)(uintptr_t)stack_base); | (*p->p_sysent->sv_setregs)(td, imgp, stack_base); | ||||
vfs_mark_atime(imgp->vp, td->td_ucred); | vfs_mark_atime(imgp->vp, td->td_ucred); | ||||
SDT_PROBE1(proc, , , exec__success, args->fname); | SDT_PROBE1(proc, , , exec__success, args->fname); | ||||
exec_fail_dealloc: | exec_fail_dealloc: | ||||
if (error != 0) { | if (error != 0) { | ||||
p->p_osrel = orig_osrel; | p->p_osrel = orig_osrel; | ||||
▲ Show 20 Lines • Show All 689 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Copy strings out to the new process address space, constructing new arg | * 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 | * and env vector tables. Return a pointer to the base so that it can be used | ||||
* as the initial stack pointer. | * as the initial stack pointer. | ||||
*/ | */ | ||||
int | int | ||||
exec_copyout_strings(struct image_params *imgp, register_t **stack_base) | exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) | ||||
{ | { | ||||
int argc, envc; | int argc, envc; | ||||
char **vectp; | char **vectp; | ||||
char *stringp; | char *stringp; | ||||
uintptr_t destp; | uintptr_t destp, ustringp; | ||||
struct ps_strings *arginfo; | struct ps_strings *arginfo; | ||||
struct proc *p; | struct proc *p; | ||||
size_t execpath_len; | size_t execpath_len; | ||||
int error, szsigcode, szps; | int error, szsigcode, szps; | ||||
char canary[sizeof(long) * 8]; | char canary[sizeof(long) * 8]; | ||||
szps = sizeof(pagesizes[0]) * MAXPAGESIZES; | szps = sizeof(pagesizes[0]) * MAXPAGESIZES; | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | exec_copyout_strings(struct image_params *imgp, uintptr_t *stack_base) | ||||
destp -= szps; | destp -= szps; | ||||
destp = rounddown2(destp, sizeof(void *)); | destp = rounddown2(destp, sizeof(void *)); | ||||
imgp->pagesizes = destp; | imgp->pagesizes = destp; | ||||
error = copyout(pagesizes, (void *)destp, szps); | error = copyout(pagesizes, (void *)destp, szps); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
imgp->pagesizeslen = szps; | imgp->pagesizeslen = szps; | ||||
/* | |||||
* Allocate room for the argument and environment strings. | |||||
*/ | |||||
destp -= ARG_MAX - imgp->args->stringspace; | destp -= ARG_MAX - imgp->args->stringspace; | ||||
destp = rounddown2(destp, sizeof(void *)); | destp = rounddown2(destp, sizeof(void *)); | ||||
ustringp = destp; | |||||
vectp = (char **)destp; | |||||
if (imgp->sysent->sv_stackgap != NULL) | if (imgp->sysent->sv_stackgap != NULL) | ||||
imgp->sysent->sv_stackgap(imgp, (u_long *)&vectp); | imgp->sysent->sv_stackgap(imgp, &destp); | ||||
if (imgp->auxargs) { | if (imgp->auxargs) { | ||||
error = imgp->sysent->sv_copyout_auxargs(imgp, | error = imgp->sysent->sv_copyout_auxargs(imgp, &destp); | ||||
(u_long *)&vectp); | |||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
} | } | ||||
vectp = (char **)destp; | |||||
/* | /* | ||||
* Allocate room for the argv[] and env vectors including the | * Allocate room for the argv[] and env vectors including the | ||||
* terminating NULL pointers. | * terminating NULL pointers. | ||||
*/ | */ | ||||
vectp -= imgp->args->argc + 1 + imgp->args->envc + 1; | vectp -= imgp->args->argc + 1 + imgp->args->envc + 1; | ||||
/* | /* | ||||
* vectp also becomes our initial stack base | * vectp also becomes our initial stack base | ||||
*/ | */ | ||||
*stack_base = (register_t *)vectp; | *stack_base = (uintptr_t)vectp; | ||||
stringp = imgp->args->begin_argv; | stringp = imgp->args->begin_argv; | ||||
argc = imgp->args->argc; | argc = imgp->args->argc; | ||||
envc = imgp->args->envc; | envc = imgp->args->envc; | ||||
/* | /* | ||||
* Copy out strings - arguments and environment. | * Copy out strings - arguments and environment. | ||||
*/ | */ | ||||
error = copyout(stringp, (void *)destp, | error = copyout(stringp, (void *)ustringp, | ||||
ARG_MAX - imgp->args->stringspace); | ARG_MAX - imgp->args->stringspace); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
/* | /* | ||||
* Fill in "ps_strings" struct for ps, w, etc. | * Fill in "ps_strings" struct for ps, w, etc. | ||||
*/ | */ | ||||
if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || | if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || | ||||
suword32(&arginfo->ps_nargvstr, argc) != 0) | suword32(&arginfo->ps_nargvstr, argc) != 0) | ||||
return (EFAULT); | return (EFAULT); | ||||
/* | /* | ||||
* Fill in argument portion of vector table. | * Fill in argument portion of vector table. | ||||
*/ | */ | ||||
for (; argc > 0; --argc) { | for (; argc > 0; --argc) { | ||||
if (suword(vectp++, (long)(intptr_t)destp) != 0) | if (suword(vectp++, ustringp) != 0) | ||||
return (EFAULT); | return (EFAULT); | ||||
while (*stringp++ != 0) | while (*stringp++ != 0) | ||||
destp++; | ustringp++; | ||||
destp++; | ustringp++; | ||||
} | } | ||||
/* a null vector table pointer separates the argp's from the envp's */ | /* a null vector table pointer separates the argp's from the envp's */ | ||||
if (suword(vectp++, 0) != 0) | if (suword(vectp++, 0) != 0) | ||||
return (EFAULT); | return (EFAULT); | ||||
if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || | if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || | ||||
suword32(&arginfo->ps_nenvstr, envc) != 0) | suword32(&arginfo->ps_nenvstr, envc) != 0) | ||||
return (EFAULT); | return (EFAULT); | ||||
/* | /* | ||||
* Fill in environment portion of vector table. | * Fill in environment portion of vector table. | ||||
*/ | */ | ||||
for (; envc > 0; --envc) { | for (; envc > 0; --envc) { | ||||
if (suword(vectp++, (long)(intptr_t)destp) != 0) | if (suword(vectp++, ustringp) != 0) | ||||
return (EFAULT); | return (EFAULT); | ||||
while (*stringp++ != 0) | while (*stringp++ != 0) | ||||
destp++; | ustringp++; | ||||
destp++; | ustringp++; | ||||
} | } | ||||
/* end of vector table is a null pointer */ | /* end of vector table is a null pointer */ | ||||
if (suword(vectp, 0) != 0) | if (suword(vectp, 0) != 0) | ||||
return (EFAULT); | return (EFAULT); | ||||
return (0); | return (0); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 132 Lines • Show Last 20 Lines |