Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/kern_exec.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/kern/kern_exec.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.138 retrieving revision 1.138.2.4 diff -u -p -r1.138 -r1.138.2.4 --- src/sys/kern/kern_exec.c 2001/02/26 20:43:25 1.138 +++ src/sys/kern/kern_exec.c 2001/09/21 22:36:24 1.138.2.4 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_exec.c,v 1.138 2001/02/26 20:43:25 lukem Exp $ */ +/* $NetBSD: kern_exec.c,v 1.138.2.4 2001/09/21 22:36:24 nathanw Exp $ */ /*- * Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,12 @@ #include #include +#ifdef DEBUG_EXEC +#define DPRINTF(a) uprintf a +#else +#define DPRINTF(a) +#endif /* DEBUG_EXEC */ + /* * Exec function switch: * @@ -131,8 +138,10 @@ const struct emul emul_netbsd = { NULL, #endif sendsig, + trapsignal, sigcode, esigcode, + setregs, NULL, NULL, NULL, @@ -212,7 +221,7 @@ check_exec(struct proc *p, struct exec_p error = EACCES; goto bad1; } - if ((vp->v_mount->mnt_flag & MNT_NOSUID) || (p->p_flag & P_TRACED)) + if (vp->v_mount->mnt_flag & MNT_NOSUID) epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID); /* try to open it */ @@ -305,7 +314,7 @@ bad1: */ /* ARGSUSED */ int -sys_execve(struct proc *p, void *v, register_t *retval) +sys_execve(struct lwp *l, void *v, register_t *retval) { struct sys_execve_args /* { syscallarg(const char *) path; @@ -316,6 +325,7 @@ sys_execve(struct proc *p, void *v, regi struct exec_package pack; struct nameidata nid; struct vattr attr; + struct proc *p; struct ucred *cred; char *argp; char * const *cpp; @@ -329,6 +339,7 @@ sys_execve(struct proc *p, void *v, regi int szsigcode; struct exec_vmcmd *base_vcp; + p = l->l_proc; cred = p->p_ucred; base_vcp = NULL; /* @@ -464,7 +475,7 @@ sys_execve(struct proc *p, void *v, regi * for remapping. Note that this might replace the current * vmspace with another! */ - uvmspace_exec(p, pack.ep_vm_minaddr, pack.ep_vm_maxaddr); + uvmspace_exec(l, pack.ep_vm_minaddr, pack.ep_vm_maxaddr); /* Now map address space */ vm = p->p_vmspace; @@ -495,16 +506,18 @@ sys_execve(struct proc *p, void *v, regi vcp->ev_addr += base_vcp->ev_addr; } error = (*vcp->ev_proc)(p, vcp); -#ifdef DEBUG +#ifdef DEBUG_EXEC if (error) { - if (i > 0) - printf("vmcmd[%d] = %#lx/%#lx @ %#lx\n", i-1, - vcp[-1].ev_addr, vcp[-1].ev_len, - vcp[-1].ev_offset); - printf("vmcmd[%d] = %#lx/%#lx @ %#lx\n", i, - vcp->ev_addr, vcp->ev_len, vcp->ev_offset); + int j; + struct exec_vmcmd *vp = &pack.ep_vmcmds.evs_cmds[0]; + for (j = 0; j <= i; j++) + uprintf( + "vmcmd[%d] = %#lx/%#lx fd@%#lx prot=0%o flags=%d\n", + j, vp[j].ev_addr, vp[j].ev_len, + vp[j].ev_offset, vp[j].ev_prot, + vp[j].ev_flags); } -#endif +#endif /* DEBUG_EXEC */ if (vcp->ev_flags & VMCMD_BASE) base_vcp = vcp; } @@ -514,9 +527,7 @@ sys_execve(struct proc *p, void *v, regi /* if an error happened, deallocate and punt */ if (error) { -#ifdef DEBUG - printf("execve: vmcmd %i failed: %d\n", i-1, error); -#endif + DPRINTF(("execve: vmcmd %i failed: %d\n", i - 1, error)); goto exec_abort; } @@ -526,12 +537,13 @@ sys_execve(struct proc *p, void *v, regi stack = (char *) (vm->vm_minsaddr - len); /* Now copy argc, args & environ to new stack */ - if (!(*pack.ep_es->es_copyargs)(&pack, &arginfo, stack, argp)) { -#ifdef DEBUG - printf("execve: copyargs failed\n"); -#endif + error = (*pack.ep_es->es_copyargs)(&pack, &arginfo, &stack, argp); + if (error) { + DPRINTF(("execve: copyargs failed %d\n", error)); goto exec_abort; } + /* Move the stack back to original point */ + stack = (char *) (vm->vm_minsaddr - len); /* fill process ps_strings info */ p->p_psstr = (struct ps_strings *)(vm->vm_minsaddr @@ -542,22 +554,19 @@ sys_execve(struct proc *p, void *v, regi p->p_psnenv = offsetof(struct ps_strings, ps_nenvstr); /* copy out the process's ps_strings structure */ - if (copyout(&arginfo, (char *)p->p_psstr, sizeof(arginfo))) { -#ifdef DEBUG - printf("execve: ps_strings copyout %p->%p size %ld failed\n", - &arginfo, (char *)p->p_psstr, (long)sizeof(arginfo)); -#endif + if ((error = copyout(&arginfo, (char *)p->p_psstr, + sizeof(arginfo))) != 0) { + DPRINTF(("execve: ps_strings copyout %p->%p size %ld failed\n", + &arginfo, (char *)p->p_psstr, (long)sizeof(arginfo))); goto exec_abort; } /* copy out the process's signal trapoline code */ if (szsigcode) { - if (copyout((char *)pack.ep_es->es_emul->e_sigcode, + if ((error = copyout((char *)pack.ep_es->es_emul->e_sigcode, p->p_sigctx.ps_sigcode = (char *)p->p_psstr - szsigcode, - szsigcode)) { -#ifdef DEBUG - printf("execve: sig trampoline copyout failed\n"); -#endif + szsigcode)) != 0) { + DPRINTF(("execve: sig trampoline copyout failed\n")); goto exec_abort; } #ifdef PMAP_NEED_PROCWR @@ -569,7 +578,12 @@ sys_execve(struct proc *p, void *v, regi stopprofclock(p); /* stop profiling */ fdcloseexec(p); /* handle close on exec */ execsigs(p); /* reset catched signals */ - p->p_ctxlink = NULL; /* reset ucontext link */ + + /* XXX NJWLWP the rest of this function probably needs its + * head examined in the context of a multilwp process. + */ + + l->l_ctxlink = NULL; /* reset ucontext link */ /* set command name & other accounting info */ len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN); @@ -591,10 +605,21 @@ sys_execve(struct proc *p, void *v, regi /* * deal with set[ug]id. - * MNT_NOSUID and P_TRACED have already been used to disable s[ug]id. + * MNT_NOSUID has already been used to disable s[ug]id. */ - if (((attr.va_mode & S_ISUID) != 0 && p->p_ucred->cr_uid != attr.va_uid) - || ((attr.va_mode & S_ISGID) != 0 && p->p_ucred->cr_gid != attr.va_gid)){ + if ((p->p_flag & P_TRACED) == 0 && + + (((attr.va_mode & S_ISUID) != 0 && + p->p_ucred->cr_uid != attr.va_uid) || + + ((attr.va_mode & S_ISGID) != 0 && + p->p_ucred->cr_gid != attr.va_gid))) { + /* + * Mark the process as SUGID before we do + * anything that might block. + */ + p_sugid(p); + p->p_ucred = crcopy(cred); #ifdef KTRACE /* @@ -608,7 +633,6 @@ sys_execve(struct proc *p, void *v, regi p->p_ucred->cr_uid = attr.va_uid; if (attr.va_mode & S_ISGID) p->p_ucred->cr_gid = attr.va_gid; - p_sugid(p); } else p->p_flag &= ~P_SUGID; p->p_cred->p_svuid = p->p_ucred->cr_uid; @@ -624,7 +648,9 @@ sys_execve(struct proc *p, void *v, regi vput(pack.ep_vp); /* setup new registers and do misc. setup. */ - (*pack.ep_es->es_setregs)(p, &pack, (u_long) stack); + (*pack.ep_es->es_emul->e_setregs)(l, &pack, (u_long) stack); + if (pack.ep_es->es_setregs) + (*pack.ep_es->es_setregs)(l, &pack, (u_long) stack); if (p->p_flag & P_TRACED) psignal(p, SIGTRAP); @@ -705,29 +731,29 @@ sys_execve(struct proc *p, void *v, regi vput(pack.ep_vp); uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS); free(pack.ep_hdr, M_EXEC); - exit1(p, W_EXITCODE(0, SIGABRT)); - exit1(p, -1); + exit1(l, W_EXITCODE(error, SIGABRT)); /* NOTREACHED */ return 0; } -void * +int copyargs(struct exec_package *pack, struct ps_strings *arginfo, - void *stack, void *argp) + char **stackp, void *argp) { char **cpp, *dp, *sp; size_t len; void *nullp; long argc, envc; + int error; - cpp = stack; + cpp = (char **)*stackp; nullp = NULL; argc = arginfo->ps_nargvstr; envc = arginfo->ps_nenvstr; - if (copyout(&argc, cpp++, sizeof(argc))) - return NULL; + if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0) + return error; dp = (char *) (cpp + argc + envc + 2 + pack->ep_es->es_arglen); sp = argp; @@ -736,24 +762,25 @@ copyargs(struct exec_package *pack, stru arginfo->ps_argvstr = cpp; /* remember location of argv for later */ for (; --argc >= 0; sp += len, dp += len) - if (copyout(&dp, cpp++, sizeof(dp)) || - copyoutstr(sp, dp, ARG_MAX, &len)) - return NULL; + if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 || + (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0) + return error; - if (copyout(&nullp, cpp++, sizeof(nullp))) - return NULL; + if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0) + return error; arginfo->ps_envstr = cpp; /* remember location of envp for later */ for (; --envc >= 0; sp += len, dp += len) - if (copyout(&dp, cpp++, sizeof(dp)) || - copyoutstr(sp, dp, ARG_MAX, &len)) - return NULL; + if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 || + (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0) + return error; - if (copyout(&nullp, cpp++, sizeof(nullp))) - return NULL; + if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0) + return error; - return cpp; + *stackp = (char *)cpp; + return 0; } #ifdef LKM