Changeset View
Changeset View
Standalone View
Standalone View
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; | register_t *stack_base; | ||||
kib: stack_base almost cries to become uintptr_t, and you are touching almost all places which need… | |||||
jhbAuthorUnsubmitted Done Inline ActionsOr a char *, but uintptr_t is probably fine. I actually planned to make this change as a followup as part of some other cleanup I am doing. I will do that as a followup change. jhb: Or a char *, but uintptr_t is probably fine. I actually planned to make this change as a… | |||||
int error, i; | int error, i; | ||||
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; | ||||
▲ Show 20 Lines • Show All 292 Lines • ▼ Show 20 Lines | #endif | ||||
/* ABI enforces the use of Capsicum. Switch into capabilities mode. */ | /* ABI enforces the use of Capsicum. Switch into capabilities mode. */ | ||||
if (SV_PROC_FLAG(p, SV_CAPSICUM)) | if (SV_PROC_FLAG(p, SV_CAPSICUM)) | ||||
sys_cap_enter(td, NULL); | sys_cap_enter(td, NULL); | ||||
/* | /* | ||||
* Copy out strings (args and env) and initialize stack base. | * Copy out strings (args and env) and initialize stack base. | ||||
*/ | */ | ||||
stack_base = (*p->p_sysent->sv_copyout_strings)(imgp); | error = (*p->p_sysent->sv_copyout_strings)(imgp, &stack_base); | ||||
if (error != 0) { | |||||
vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | |||||
goto exec_fail_dealloc; | |||||
} | |||||
/* | /* | ||||
* Stack setup. | * Stack setup. | ||||
*/ | */ | ||||
error = (*p->p_sysent->sv_fixup)(&stack_base, imgp); | error = (*p->p_sysent->sv_fixup)(&stack_base, imgp); | ||||
if (error != 0) { | if (error != 0) { | ||||
vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | ||||
goto exec_fail_dealloc; | goto exec_fail_dealloc; | ||||
▲ Show 20 Lines • Show All 875 Lines • ▼ Show 20 Lines | exec_args_get_begin_envv(struct image_args *args) | ||||
return (args->endp); | return (args->endp); | ||||
} | } | ||||
/* | /* | ||||
* 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. | ||||
*/ | */ | ||||
register_t * | int | ||||
exec_copyout_strings(struct image_params *imgp) | exec_copyout_strings(struct image_params *imgp, register_t **stack_base) | ||||
{ | { | ||||
int argc, envc; | int argc, envc; | ||||
char **vectp; | char **vectp; | ||||
char *stringp; | char *stringp; | ||||
uintptr_t destp; | uintptr_t destp; | ||||
register_t *stack_base; | |||||
struct ps_strings *arginfo; | struct ps_strings *arginfo; | ||||
struct proc *p; | struct proc *p; | ||||
size_t execpath_len; | size_t execpath_len; | ||||
int 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; | ||||
/* | /* | ||||
* Calculate string base and vector table pointers. | * Calculate string base and vector table pointers. | ||||
* Also deal with signal trampoline code for this exec type. | * Also deal with signal trampoline code for this exec type. | ||||
*/ | */ | ||||
if (imgp->execpath != NULL && imgp->auxargs != NULL) | if (imgp->execpath != NULL && imgp->auxargs != NULL) | ||||
Show All 10 Lines | exec_copyout_strings(struct image_params *imgp, register_t **stack_base) | ||||
destp = (uintptr_t)arginfo; | destp = (uintptr_t)arginfo; | ||||
/* | /* | ||||
* install sigcode | * install sigcode | ||||
*/ | */ | ||||
if (szsigcode != 0) { | if (szsigcode != 0) { | ||||
destp -= szsigcode; | destp -= szsigcode; | ||||
destp = rounddown2(destp, sizeof(void *)); | destp = rounddown2(destp, sizeof(void *)); | ||||
copyout(p->p_sysent->sv_sigcode, (void *)destp, szsigcode); | error = copyout(p->p_sysent->sv_sigcode, (void *)destp, | ||||
szsigcode); | |||||
if (error) | |||||
return (error); | |||||
} | } | ||||
/* | /* | ||||
* Copy the image path for the rtld. | * Copy the image path for the rtld. | ||||
*/ | */ | ||||
if (execpath_len != 0) { | if (execpath_len != 0) { | ||||
destp -= execpath_len; | destp -= execpath_len; | ||||
destp = rounddown2(destp, sizeof(void *)); | destp = rounddown2(destp, sizeof(void *)); | ||||
imgp->execpathp = destp; | imgp->execpathp = destp; | ||||
copyout(imgp->execpath, (void *)destp, execpath_len); | error = copyout(imgp->execpath, (void *)destp, execpath_len); | ||||
if (error) | |||||
return (error); | |||||
} | } | ||||
/* | /* | ||||
* Prepare the canary for SSP. | * Prepare the canary for SSP. | ||||
*/ | */ | ||||
arc4rand(canary, sizeof(canary), 0); | arc4rand(canary, sizeof(canary), 0); | ||||
destp -= sizeof(canary); | destp -= sizeof(canary); | ||||
imgp->canary = destp; | imgp->canary = destp; | ||||
copyout(canary, (void *)destp, sizeof(canary)); | error = copyout(canary, (void *)destp, sizeof(canary)); | ||||
if (error) | |||||
return (error); | |||||
imgp->canarylen = sizeof(canary); | imgp->canarylen = sizeof(canary); | ||||
/* | /* | ||||
* Prepare the pagesizes array. | * Prepare the pagesizes array. | ||||
*/ | */ | ||||
destp -= szps; | destp -= szps; | ||||
destp = rounddown2(destp, sizeof(void *)); | destp = rounddown2(destp, sizeof(void *)); | ||||
imgp->pagesizes = destp; | imgp->pagesizes = destp; | ||||
copyout(pagesizes, (void *)destp, szps); | error = copyout(pagesizes, (void *)destp, szps); | ||||
if (error) | |||||
return (error); | |||||
imgp->pagesizeslen = szps; | imgp->pagesizeslen = szps; | ||||
destp -= ARG_MAX - imgp->args->stringspace; | destp -= ARG_MAX - imgp->args->stringspace; | ||||
destp = rounddown2(destp, sizeof(void *)); | destp = rounddown2(destp, sizeof(void *)); | ||||
vectp = (char **)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, (u_long *)&vectp); | ||||
if (imgp->auxargs) | if (imgp->auxargs) { | ||||
imgp->sysent->sv_copyout_auxargs(imgp, (u_long *)&vectp); | error = imgp->sysent->sv_copyout_auxargs(imgp, | ||||
(u_long *)&vectp); | |||||
if (error) | |||||
return (error); | |||||
} | |||||
/* | /* | ||||
* 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 = (register_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. | ||||
*/ | */ | ||||
copyout(stringp, (void *)destp, ARG_MAX - imgp->args->stringspace); | error = copyout(stringp, (void *)destp, | ||||
ARG_MAX - imgp->args->stringspace); | |||||
if (error) | |||||
return (error); | |||||
/* | /* | ||||
* Fill in "ps_strings" struct for ps, w, etc. | * Fill in "ps_strings" struct for ps, w, etc. | ||||
*/ | */ | ||||
suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp); | if (suword(&arginfo->ps_argvstr, (long)(intptr_t)vectp) != 0 || | ||||
suword32(&arginfo->ps_nargvstr, argc); | suword32(&arginfo->ps_nargvstr, argc) != 0) | ||||
return (EFAULT); | |||||
/* | /* | ||||
* Fill in argument portion of vector table. | * Fill in argument portion of vector table. | ||||
*/ | */ | ||||
for (; argc > 0; --argc) { | for (; argc > 0; --argc) { | ||||
suword(vectp++, (long)(intptr_t)destp); | if (suword(vectp++, (long)(intptr_t)destp) != 0) | ||||
return (EFAULT); | |||||
while (*stringp++ != 0) | while (*stringp++ != 0) | ||||
destp++; | destp++; | ||||
destp++; | destp++; | ||||
} | } | ||||
/* 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 */ | ||||
suword(vectp++, 0); | if (suword(vectp++, 0) != 0) | ||||
return (EFAULT); | |||||
suword(&arginfo->ps_envstr, (long)(intptr_t)vectp); | if (suword(&arginfo->ps_envstr, (long)(intptr_t)vectp) != 0 || | ||||
suword32(&arginfo->ps_nenvstr, envc); | suword32(&arginfo->ps_nenvstr, envc) != 0) | ||||
return (EFAULT); | |||||
/* | /* | ||||
* Fill in environment portion of vector table. | * Fill in environment portion of vector table. | ||||
*/ | */ | ||||
for (; envc > 0; --envc) { | for (; envc > 0; --envc) { | ||||
suword(vectp++, (long)(intptr_t)destp); | if (suword(vectp++, (long)(intptr_t)destp) != 0) | ||||
return (EFAULT); | |||||
while (*stringp++ != 0) | while (*stringp++ != 0) | ||||
destp++; | destp++; | ||||
destp++; | destp++; | ||||
} | } | ||||
/* end of vector table is a null pointer */ | /* end of vector table is a null pointer */ | ||||
suword(vectp, 0); | if (suword(vectp, 0) != 0) | ||||
return (EFAULT); | |||||
return (stack_base); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Check permissions of file to execute. | * Check permissions of file to execute. | ||||
* Called with imgp->vp locked. | * Called with imgp->vp locked. | ||||
* Return 0 for success or error code on failure. | * Return 0 for success or error code on failure. | ||||
*/ | */ | ||||
int | int | ||||
▲ Show 20 Lines • Show All 125 Lines • Show Last 20 Lines |
stack_base almost cries to become uintptr_t, and you are touching almost all places which need explicit type for it. Then at least some casts could be removed, like sv_setregs calls.
But I do not insist.