version 1.209.2.1, 2005/11/02 11:58:11 |
version 1.210, 2005/10/31 04:31:58 |
Line 204 static void link_es(struct execsw_entry |
|
Line 204 static void link_es(struct execsw_entry |
|
* |
* |
* ON ENTRY: |
* ON ENTRY: |
* exec package with appropriate namei info |
* exec package with appropriate namei info |
* proc pointer of exec'ing proc |
* lwp pointer of exec'ing proc |
* if verified exec enabled then flag indicating a direct exec or |
* if verified exec enabled then flag indicating a direct exec or |
* an indirect exec (i.e. for a shell script interpreter) |
* an indirect exec (i.e. for a shell script interpreter) |
* NO SELF-LOCKED VNODES |
* NO SELF-LOCKED VNODES |
Line 226 static void link_es(struct execsw_entry |
|
Line 226 static void link_es(struct execsw_entry |
|
*/ |
*/ |
int |
int |
/*ARGSUSED*/ |
/*ARGSUSED*/ |
check_exec(struct proc *p, struct exec_package *epp, int flag) |
check_exec(struct lwp *l, struct exec_package *epp, int flag) |
{ |
{ |
int error, i; |
int error, i; |
struct vnode *vp; |
struct vnode *vp; |
struct nameidata *ndp; |
struct nameidata *ndp; |
size_t resid; |
size_t resid; |
|
struct proc *p = l->l_proc; |
|
|
ndp = epp->ep_ndp; |
ndp = epp->ep_ndp; |
ndp->ni_cnd.cn_nameiop = LOOKUP; |
ndp->ni_cnd.cn_nameiop = LOOKUP; |
Line 246 check_exec(struct proc *p, struct exec_p |
|
Line 247 check_exec(struct proc *p, struct exec_p |
|
error = EACCES; |
error = EACCES; |
goto bad1; |
goto bad1; |
} |
} |
if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0) |
if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, l)) != 0) |
goto bad1; |
goto bad1; |
|
|
/* get attributes */ |
/* get attributes */ |
if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0) |
if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, l)) != 0) |
goto bad1; |
goto bad1; |
|
|
/* Check mount point */ |
/* Check mount point */ |
Line 262 check_exec(struct proc *p, struct exec_p |
|
Line 263 check_exec(struct proc *p, struct exec_p |
|
epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID); |
epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID); |
|
|
/* try to open it */ |
/* try to open it */ |
if ((error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) != 0) |
if ((error = VOP_OPEN(vp, FREAD, p->p_ucred, l)) != 0) |
goto bad1; |
goto bad1; |
|
|
/* unlock vp, since we need it unlocked from here on out. */ |
/* unlock vp, since we need it unlocked from here on out. */ |
Line 270 check_exec(struct proc *p, struct exec_p |
|
Line 271 check_exec(struct proc *p, struct exec_p |
|
|
|
|
|
#ifdef VERIFIED_EXEC |
#ifdef VERIFIED_EXEC |
if ((error = veriexec_verify(p, vp, epp->ep_vap, epp->ep_ndp->ni_dirp, |
if ((error = veriexec_verify(l, vp, epp->ep_vap, epp->ep_ndp->ni_dirp, |
flag, NULL)) != 0) |
flag, NULL)) != 0) |
goto bad2; |
goto bad2; |
#endif |
#endif |
Line 300 check_exec(struct proc *p, struct exec_p |
|
Line 301 check_exec(struct proc *p, struct exec_p |
|
int newerror; |
int newerror; |
|
|
epp->ep_esch = execsw[i]; |
epp->ep_esch = execsw[i]; |
newerror = (*execsw[i]->es_makecmds)(p, epp); |
newerror = (*execsw[i]->es_makecmds)(l, epp); |
/* make sure the first "interesting" error code is saved. */ |
/* make sure the first "interesting" error code is saved. */ |
if (!newerror || error == ENOEXEC) |
if (!newerror || error == ENOEXEC) |
error = newerror; |
error = newerror; |
|
|
* pathname buf, and punt. |
* pathname buf, and punt. |
*/ |
*/ |
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
VOP_CLOSE(vp, FREAD, p->p_ucred, p); |
VOP_CLOSE(vp, FREAD, p->p_ucred, l); |
vput(vp); |
vput(vp); |
PNBUF_PUT(ndp->ni_cnd.cn_pnbuf); |
PNBUF_PUT(ndp->ni_cnd.cn_pnbuf); |
return error; |
return error; |
Line 444 execve1(struct lwp *l, const char *path, |
|
Line 445 execve1(struct lwp *l, const char *path, |
|
if (error) |
if (error) |
goto clrflg; |
goto clrflg; |
|
|
NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_SYSSPACE, pathbuf, p); |
NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_SYSSPACE, pathbuf, l); |
#else |
#else |
NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, path, p); |
NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, path, l); |
#endif /* SYSTRACE */ |
#endif /* SYSTRACE */ |
|
|
/* |
/* |
Line 473 execve1(struct lwp *l, const char *path, |
|
Line 474 execve1(struct lwp *l, const char *path, |
|
|
|
/* see if we can run it. */ |
/* see if we can run it. */ |
#ifdef VERIFIED_EXEC |
#ifdef VERIFIED_EXEC |
if ((error = check_exec(p, &pack, VERIEXEC_DIRECT)) != 0) |
if ((error = check_exec(l, &pack, VERIEXEC_DIRECT)) != 0) |
#else |
#else |
if ((error = check_exec(p, &pack, 0)) != 0) |
if ((error = check_exec(l, &pack, 0)) != 0) |
#endif |
#endif |
goto freehdr; |
goto freehdr; |
|
|
Line 532 execve1(struct lwp *l, const char *path, |
|
Line 533 execve1(struct lwp *l, const char *path, |
|
} |
} |
#ifdef KTRACE |
#ifdef KTRACE |
if (KTRPOINT(p, KTR_EXEC_ARG)) |
if (KTRPOINT(p, KTR_EXEC_ARG)) |
ktrkmem(p, KTR_EXEC_ARG, dp, len - 1); |
ktrkmem(l, KTR_EXEC_ARG, dp, len - 1); |
#endif |
#endif |
dp += len; |
dp += len; |
i++; |
i++; |
Line 556 execve1(struct lwp *l, const char *path, |
|
Line 557 execve1(struct lwp *l, const char *path, |
|
} |
} |
#ifdef KTRACE |
#ifdef KTRACE |
if (KTRPOINT(p, KTR_EXEC_ENV)) |
if (KTRPOINT(p, KTR_EXEC_ENV)) |
ktrkmem(p, KTR_EXEC_ENV, dp, len - 1); |
ktrkmem(l, KTR_EXEC_ENV, dp, len - 1); |
#endif |
#endif |
dp += len; |
dp += len; |
i++; |
i++; |
Line 649 execve1(struct lwp *l, const char *path, |
|
Line 650 execve1(struct lwp *l, const char *path, |
|
#endif |
#endif |
vcp->ev_addr += base_vcp->ev_addr; |
vcp->ev_addr += base_vcp->ev_addr; |
} |
} |
error = (*vcp->ev_proc)(p, vcp); |
error = (*vcp->ev_proc)(l, vcp); |
#ifdef DEBUG_EXEC |
#ifdef DEBUG_EXEC |
if (error) { |
if (error) { |
int j; |
int j; |
Line 670 execve1(struct lwp *l, const char *path, |
|
Line 671 execve1(struct lwp *l, const char *path, |
|
kill_vmcmds(&pack.ep_vmcmds); |
kill_vmcmds(&pack.ep_vmcmds); |
|
|
vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY); |
vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY); |
VOP_CLOSE(pack.ep_vp, FREAD, cred, p); |
VOP_CLOSE(pack.ep_vp, FREAD, cred, l); |
vput(pack.ep_vp); |
vput(pack.ep_vp); |
|
|
/* if an error happened, deallocate and punt */ |
/* if an error happened, deallocate and punt */ |
Line 714 execve1(struct lwp *l, const char *path, |
|
Line 715 execve1(struct lwp *l, const char *path, |
|
#endif /* __MACHINE_STACK_GROWS_UP */ |
#endif /* __MACHINE_STACK_GROWS_UP */ |
|
|
/* Now copy argc, args & environ to new stack */ |
/* Now copy argc, args & environ to new stack */ |
error = (*pack.ep_es->es_copyargs)(p, &pack, &arginfo, &stack, argp); |
error = (*pack.ep_es->es_copyargs)(l, &pack, &arginfo, &stack, argp); |
if (error) { |
if (error) { |
DPRINTF(("execve: copyargs failed %d\n", error)); |
DPRINTF(("execve: copyargs failed %d\n", error)); |
goto exec_abort; |
goto exec_abort; |
Line 740 execve1(struct lwp *l, const char *path, |
|
Line 741 execve1(struct lwp *l, const char *path, |
|
} |
} |
|
|
stopprofclock(p); /* stop profiling */ |
stopprofclock(p); /* stop profiling */ |
fdcloseexec(p); /* handle close on exec */ |
fdcloseexec(l); /* handle close on exec */ |
execsigs(p); /* reset catched signals */ |
execsigs(p); /* reset catched signals */ |
|
|
l->l_ctxlink = NULL; /* reset ucontext link */ |
l->l_ctxlink = NULL; /* reset ucontext link */ |
Line 775 execve1(struct lwp *l, const char *path, |
|
Line 776 execve1(struct lwp *l, const char *path, |
|
p_sugid(p); |
p_sugid(p); |
|
|
/* Make sure file descriptors 0..2 are in use. */ |
/* Make sure file descriptors 0..2 are in use. */ |
if ((error = fdcheckstd(p)) != 0) { |
if ((error = fdcheckstd(l)) != 0) { |
DPRINTF(("execve: fdcheckstd failed %d\n", error)); |
DPRINTF(("execve: fdcheckstd failed %d\n", error)); |
goto exec_abort; |
goto exec_abort; |
} |
} |
Line 865 execve1(struct lwp *l, const char *path, |
|
Line 866 execve1(struct lwp *l, const char *path, |
|
#endif |
#endif |
#ifdef KTRACE |
#ifdef KTRACE |
if (KTRPOINT(p, KTR_EMUL)) |
if (KTRPOINT(p, KTR_EMUL)) |
ktremul(p); |
ktremul(l); |
#endif |
#endif |
|
|
#ifdef LKM |
#ifdef LKM |
Line 902 execve1(struct lwp *l, const char *path, |
|
Line 903 execve1(struct lwp *l, const char *path, |
|
/* kill any opened file descriptor, if necessary */ |
/* kill any opened file descriptor, if necessary */ |
if (pack.ep_flags & EXEC_HASFD) { |
if (pack.ep_flags & EXEC_HASFD) { |
pack.ep_flags &= ~EXEC_HASFD; |
pack.ep_flags &= ~EXEC_HASFD; |
(void) fdrelease(p, pack.ep_fd); |
(void) fdrelease(l, pack.ep_fd); |
} |
} |
/* close and put the exec'd file */ |
/* close and put the exec'd file */ |
vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY); |
vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY); |
VOP_CLOSE(pack.ep_vp, FREAD, cred, p); |
VOP_CLOSE(pack.ep_vp, FREAD, cred, l); |
vput(pack.ep_vp); |
vput(pack.ep_vp); |
PNBUF_PUT(nid.ni_cnd.cn_pnbuf); |
PNBUF_PUT(nid.ni_cnd.cn_pnbuf); |
uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE); |
uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE); |
Line 951 execve1(struct lwp *l, const char *path, |
|
Line 952 execve1(struct lwp *l, const char *path, |
|
|
|
|
|
int |
int |
copyargs(struct proc *p, struct exec_package *pack, struct ps_strings *arginfo, |
copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo, |
char **stackp, void *argp) |
char **stackp, void *argp) |
{ |
{ |
char **cpp, *dp, *sp; |
char **cpp, *dp, *sp; |