Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_exec.c
Show First 20 Lines • Show All 353 Lines • ▼ Show 20 Lines | |||||
* userspace pointers from the passed thread. | * userspace pointers from the passed thread. | ||||
*/ | */ | ||||
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 credwrap *oldcredwrap; | |||||
struct uidinfo *euip = NULL; | struct uidinfo *euip = NULL; | ||||
uintptr_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 | ||||
Show All 31 Lines | #endif | ||||
/* | /* | ||||
* Initialize part of the common data | * Initialize part of the common data | ||||
*/ | */ | ||||
bzero(imgp, sizeof(*imgp)); | bzero(imgp, sizeof(*imgp)); | ||||
imgp->proc = p; | imgp->proc = p; | ||||
imgp->attr = &attr; | imgp->attr = &attr; | ||||
imgp->args = args; | imgp->args = args; | ||||
oldcred = p->p_ucred; | oldcred = p->p_ucred; | ||||
oldcredwrap = p->p_credwrap; | |||||
orig_osrel = p->p_osrel; | orig_osrel = p->p_osrel; | ||||
orig_fctl0 = p->p_fctl0; | orig_fctl0 = p->p_fctl0; | ||||
#ifdef MAC | #ifdef MAC | ||||
error = mac_execve_enter(imgp, mac_p); | error = mac_execve_enter(imgp, mac_p); | ||||
if (error) | if (error) | ||||
goto exec_fail; | goto exec_fail; | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | |||||
#ifdef CAPABILITY_MODE | #ifdef CAPABILITY_MODE | ||||
((oldcred->cr_flags & CRED_FLAG_CAPMODE) == 0) && | ((oldcred->cr_flags & CRED_FLAG_CAPMODE) == 0) && | ||||
#endif | #endif | ||||
(imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && | (imgp->vp->v_mount->mnt_flag & MNT_NOSUID) == 0 && | ||||
(p->p_flag & P_TRACED) == 0) { | (p->p_flag & P_TRACED) == 0) { | ||||
imgp->credential_setid = true; | imgp->credential_setid = true; | ||||
VOP_UNLOCK(imgp->vp, 0); | VOP_UNLOCK(imgp->vp, 0); | ||||
imgp->newcred = crdup(oldcred); | imgp->newcred = crdup(oldcred); | ||||
imgp->newcredwrap = crwget(imgp->newcred); | |||||
if (attr.va_mode & S_ISUID) { | if (attr.va_mode & S_ISUID) { | ||||
euip = uifind(attr.va_uid); | euip = uifind(attr.va_uid); | ||||
change_euid(imgp->newcred, euip); | change_euid(imgp->newcred, euip); | ||||
} | } | ||||
vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | vn_lock(imgp->vp, LK_SHARED | LK_RETRY); | ||||
if (attr.va_mode & S_ISGID) | if (attr.va_mode & S_ISGID) | ||||
change_egid(imgp->newcred, attr.va_gid); | change_egid(imgp->newcred, attr.va_gid); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 268 Lines • ▼ Show 20 Lines | #endif | ||||
if (oldcred->cr_uid == oldcred->cr_ruid && | if (oldcred->cr_uid == oldcred->cr_ruid && | ||||
oldcred->cr_gid == oldcred->cr_rgid) | oldcred->cr_gid == oldcred->cr_rgid) | ||||
p->p_flag &= ~P_SUGID; | p->p_flag &= ~P_SUGID; | ||||
} | } | ||||
/* | /* | ||||
* Set the new credentials. | * Set the new credentials. | ||||
*/ | */ | ||||
if (imgp->newcred != NULL) { | if (imgp->newcred != NULL) { | ||||
proc_set_cred(p, imgp->newcred); | proc_set_cred(p, imgp->newcred, imgp->newcredwrap); | ||||
crfree(oldcred); | crfree(oldcred); | ||||
crwfree(oldcredwrap); | |||||
oldcred = NULL; | oldcred = NULL; | ||||
oldcredwrap = NULL; | |||||
} | } | ||||
/* | /* | ||||
* Store the vp for use in procfs. This vnode was referenced by namei | * Store the vp for use in procfs. This vnode was referenced by namei | ||||
* or fgetvp_exec. | * or fgetvp_exec. | ||||
*/ | */ | ||||
oldtextvp = p->p_textvp; | oldtextvp = p->p_textvp; | ||||
p->p_textvp = newtextvp; | p->p_textvp = newtextvp; | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | exec_fail: | ||||
/* we're done here, clear P_INEXEC */ | /* we're done here, clear P_INEXEC */ | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
p->p_flag &= ~P_INEXEC; | p->p_flag &= ~P_INEXEC; | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
SDT_PROBE1(proc, , , exec__failure, error); | SDT_PROBE1(proc, , , exec__failure, error); | ||||
} | } | ||||
if (imgp->newcred != NULL && oldcred != NULL) | if (imgp->newcred != NULL && oldcred != NULL) { | ||||
crfree(imgp->newcred); | crfree(imgp->newcred); | ||||
crwfree(imgp->newcredwrap); | |||||
} | |||||
#ifdef MAC | #ifdef MAC | ||||
mac_execve_exit(imgp); | mac_execve_exit(imgp); | ||||
mac_execve_interpreter_exit(interpvplabel); | mac_execve_interpreter_exit(interpvplabel); | ||||
#endif | #endif | ||||
exec_free_args(args); | exec_free_args(args); | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 943 Lines • Show Last 20 Lines |