Annotation of src/sys/kern/kern_exec.c, Revision 1.243.2.2
1.243.2.2! ad 1: /* $NetBSD: kern_exec.c,v 1.243.2.1 2007/06/08 14:17:17 ad Exp $ */
1.55 cgd 2:
3: /*-
1.77 cgd 4: * Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou
1.55 cgd 5: * Copyright (C) 1992 Wolfgang Solfrank.
6: * Copyright (C) 1992 TooLs GmbH.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by TooLs GmbH.
20: * 4. The name of TooLs GmbH may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33: */
1.146 lukem 34:
35: #include <sys/cdefs.h>
1.243.2.2! ad 36: __KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.243.2.1 2007/06/08 14:17:17 ad Exp $");
1.89 mrg 37:
1.92 thorpej 38: #include "opt_ktrace.h"
1.124 jdolecek 39: #include "opt_syscall_debug.h"
1.174 christos 40: #include "opt_compat_netbsd.h"
1.226 dogcow 41: #include "veriexec.h"
1.232 elad 42: #include "opt_pax.h"
1.55 cgd 43:
44: #include <sys/param.h>
45: #include <sys/systm.h>
46: #include <sys/filedesc.h>
47: #include <sys/kernel.h>
48: #include <sys/proc.h>
49: #include <sys/mount.h>
50: #include <sys/malloc.h>
51: #include <sys/namei.h>
52: #include <sys/vnode.h>
53: #include <sys/file.h>
54: #include <sys/acct.h>
55: #include <sys/exec.h>
56: #include <sys/ktrace.h>
57: #include <sys/resourcevar.h>
58: #include <sys/wait.h>
59: #include <sys/mman.h>
1.155 gmcgarry 60: #include <sys/ras.h>
1.55 cgd 61: #include <sys/signalvar.h>
62: #include <sys/stat.h>
1.124 jdolecek 63: #include <sys/syscall.h>
1.218 elad 64: #include <sys/kauth.h>
1.55 cgd 65:
1.56 cgd 66: #include <sys/syscallargs.h>
1.222 elad 67: #if NVERIEXEC > 0
1.197 blymn 68: #include <sys/verified_exec.h>
1.222 elad 69: #endif /* NVERIEXEC > 0 */
1.55 cgd 70:
1.200 elad 71: #ifdef SYSTRACE
72: #include <sys/systrace.h>
73: #endif /* SYSTRACE */
74:
1.232 elad 75: #ifdef PAX_SEGVGUARD
76: #include <sys/pax.h>
77: #endif /* PAX_SEGVGUARD */
78:
1.88 mrg 79: #include <uvm/uvm_extern.h>
80:
1.55 cgd 81: #include <machine/cpu.h>
82: #include <machine/reg.h>
83:
1.243.2.1 ad 84: #include <compat/common/compat_util.h>
85:
1.171 chs 86: static int exec_sigcode_map(struct proc *, const struct emul *);
87:
1.143 christos 88: #ifdef DEBUG_EXEC
89: #define DPRINTF(a) uprintf a
90: #else
91: #define DPRINTF(a)
92: #endif /* DEBUG_EXEC */
1.165 thorpej 93:
94: MALLOC_DEFINE(M_EXEC, "exec", "argument lists & other mem used by exec");
1.143 christos 95:
1.130 jdolecek 96: /*
97: * Exec function switch:
98: *
99: * Note that each makecmds function is responsible for loading the
100: * exec package with the necessary functions for any exec-type-specific
101: * handling.
102: *
103: * Functions for specific exec types should be defined in their own
104: * header file.
105: */
1.138 lukem 106: extern const struct execsw execsw_builtin[];
107: extern int nexecs_builtin;
108: static const struct execsw **execsw = NULL;
109: static int nexecs;
110:
1.153 thorpej 111: u_int exec_maxhdrsz; /* must not be static - netbsd32 needs it */
1.130 jdolecek 112:
113: #ifdef LKM
114: /* list of supported emulations */
115: static
116: LIST_HEAD(emlist_head, emul_entry) el_head = LIST_HEAD_INITIALIZER(el_head);
117: struct emul_entry {
1.138 lukem 118: LIST_ENTRY(emul_entry) el_list;
119: const struct emul *el_emul;
120: int ro_entry;
1.130 jdolecek 121: };
122:
123: /* list of dynamically loaded execsw entries */
124: static
125: LIST_HEAD(execlist_head, exec_entry) ex_head = LIST_HEAD_INITIALIZER(ex_head);
126: struct exec_entry {
1.138 lukem 127: LIST_ENTRY(exec_entry) ex_list;
128: const struct execsw *es;
1.130 jdolecek 129: };
130:
131: /* structure used for building execw[] */
132: struct execsw_entry {
1.138 lukem 133: struct execsw_entry *next;
134: const struct execsw *es;
1.130 jdolecek 135: };
136: #endif /* LKM */
137:
1.124 jdolecek 138: #ifdef SYSCALL_DEBUG
139: extern const char * const syscallnames[];
140: #endif
141:
1.185 drochner 142: #ifdef COMPAT_16
1.173 christos 143: extern char sigcode[], esigcode[];
1.171 chs 144: struct uvm_object *emul_netbsd_object;
1.173 christos 145: #endif
1.171 chs 146:
1.203 christos 147: #ifndef __HAVE_SYSCALL_INTERN
148: void syscall(void);
149: #endif
150:
1.173 christos 151: /* NetBSD emul struct */
1.124 jdolecek 152: const struct emul emul_netbsd = {
153: "netbsd",
1.127 jdolecek 154: NULL, /* emulation path */
1.133 mycroft 155: #ifndef __HAVE_MINIMAL_EMUL
1.140 manu 156: EMUL_HAS_SYS___syscall,
1.124 jdolecek 157: NULL,
158: SYS_syscall,
1.161 jdolecek 159: SYS_NSYSENT,
1.133 mycroft 160: #endif
1.124 jdolecek 161: sysent,
162: #ifdef SYSCALL_DEBUG
163: syscallnames,
164: #else
165: NULL,
166: #endif
1.133 mycroft 167: sendsig,
1.142 christos 168: trapsignal,
1.180 fvdl 169: NULL,
1.185 drochner 170: #ifdef COMPAT_16
1.124 jdolecek 171: sigcode,
172: esigcode,
1.171 chs 173: &emul_netbsd_object,
1.173 christos 174: #else
175: NULL,
176: NULL,
177: NULL,
178: #endif
1.145 jdolecek 179: setregs,
1.128 jdolecek 180: NULL,
181: NULL,
182: NULL,
1.179 manu 183: NULL,
184: NULL,
1.133 mycroft 185: #ifdef __HAVE_SYSCALL_INTERN
186: syscall_intern,
187: #else
188: syscall,
189: #endif
1.156 manu 190: NULL,
191: NULL,
1.195 fvdl 192:
193: uvm_default_mapaddr,
1.216 cube 194: NULL,
1.237 ad 195: sizeof(ucontext_t),
1.239 cube 196: startlwp,
1.124 jdolecek 197: };
198:
1.147 jdolecek 199: #ifdef LKM
1.55 cgd 200: /*
1.130 jdolecek 201: * Exec lock. Used to control access to execsw[] structures.
202: * This must not be static so that netbsd32 can access it, too.
203: */
1.237 ad 204: krwlock_t exec_lock;
1.183 junyoung 205:
1.138 lukem 206: static void link_es(struct execsw_entry **, const struct execsw *);
1.130 jdolecek 207: #endif /* LKM */
208:
209: /*
1.55 cgd 210: * check exec:
211: * given an "executable" described in the exec package's namei info,
212: * see what we can do with it.
213: *
214: * ON ENTRY:
215: * exec package with appropriate namei info
1.212 christos 216: * lwp pointer of exec'ing lwp
1.55 cgd 217: * NO SELF-LOCKED VNODES
218: *
219: * ON EXIT:
220: * error: nothing held, etc. exec header still allocated.
1.77 cgd 221: * ok: filled exec package, executable's vnode (unlocked).
1.55 cgd 222: *
223: * EXEC SWITCH ENTRY:
224: * Locked vnode to check, exec package, proc.
225: *
226: * EXEC SWITCH EXIT:
1.77 cgd 227: * ok: return 0, filled exec package, executable's vnode (unlocked).
1.55 cgd 228: * error: destructive:
229: * everything deallocated execept exec header.
1.76 cgd 230: * non-destructive:
1.77 cgd 231: * error code, executable's vnode (unlocked),
1.76 cgd 232: * exec header unmodified.
1.55 cgd 233: */
234: int
1.205 christos 235: /*ARGSUSED*/
1.233 elad 236: check_exec(struct lwp *l, struct exec_package *epp)
1.55 cgd 237: {
1.138 lukem 238: int error, i;
239: struct vnode *vp;
1.55 cgd 240: struct nameidata *ndp;
1.138 lukem 241: size_t resid;
1.55 cgd 242:
243: ndp = epp->ep_ndp;
244: ndp->ni_cnd.cn_nameiop = LOOKUP;
1.243.2.1 ad 245: ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | SAVENAME | TRYEMULROOT;
1.55 cgd 246: /* first get the vnode */
1.74 christos 247: if ((error = namei(ndp)) != 0)
1.55 cgd 248: return error;
249: epp->ep_vp = vp = ndp->ni_vp;
250:
1.84 mycroft 251: /* check access and type */
1.55 cgd 252: if (vp->v_type != VREG) {
1.81 kleink 253: error = EACCES;
1.55 cgd 254: goto bad1;
255: }
1.223 ad 256: if ((error = VOP_ACCESS(vp, VEXEC, l->l_cred, l)) != 0)
1.84 mycroft 257: goto bad1;
1.55 cgd 258:
259: /* get attributes */
1.223 ad 260: if ((error = VOP_GETATTR(vp, epp->ep_vap, l->l_cred, l)) != 0)
1.55 cgd 261: goto bad1;
262:
263: /* Check mount point */
264: if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
265: error = EACCES;
266: goto bad1;
267: }
1.141 thorpej 268: if (vp->v_mount->mnt_flag & MNT_NOSUID)
1.83 mycroft 269: epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
1.55 cgd 270:
271: /* try to open it */
1.223 ad 272: if ((error = VOP_OPEN(vp, FREAD, l->l_cred, l)) != 0)
1.55 cgd 273: goto bad1;
274:
1.99 wrstuden 275: /* unlock vp, since we need it unlocked from here on out. */
1.90 fvdl 276: VOP_UNLOCK(vp, 0);
1.77 cgd 277:
1.222 elad 278: #if NVERIEXEC > 0
1.236 elad 279: error = veriexec_verify(l, vp, ndp->ni_cnd.cn_pnbuf,
1.233 elad 280: epp->ep_flags & EXEC_INDIR ? VERIEXEC_INDIRECT : VERIEXEC_DIRECT,
1.236 elad 281: NULL);
282: if (error)
1.234 elad 283: goto bad2;
1.222 elad 284: #endif /* NVERIEXEC > 0 */
1.160 blymn 285:
1.232 elad 286: #ifdef PAX_SEGVGUARD
1.240 thorpej 287: error = pax_segvguard(l, vp, ndp->ni_cnd.cn_pnbuf, false);
1.234 elad 288: if (error)
289: goto bad2;
1.232 elad 290: #endif /* PAX_SEGVGUARD */
291:
1.55 cgd 292: /* now we have the file, get the exec header */
1.74 christos 293: error = vn_rdwr(UIO_READ, vp, epp->ep_hdr, epp->ep_hdrlen, 0,
1.223 ad 294: UIO_SYSSPACE, 0, l->l_cred, &resid, NULL);
1.74 christos 295: if (error)
1.55 cgd 296: goto bad2;
297: epp->ep_hdrvalid = epp->ep_hdrlen - resid;
298:
299: /*
1.136 eeh 300: * Set up default address space limits. Can be overridden
301: * by individual exec packages.
1.183 junyoung 302: *
1.235 rillig 303: * XXX probably should be all done in the exec packages.
1.136 eeh 304: */
305: epp->ep_vm_minaddr = VM_MIN_ADDRESS;
306: epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS;
307: /*
1.55 cgd 308: * set up the vmcmds for creation of the process
309: * address space
310: */
311: error = ENOEXEC;
1.243.2.1 ad 312: for (i = 0; i < nexecs; i++) {
1.68 cgd 313: int newerror;
314:
1.130 jdolecek 315: epp->ep_esch = execsw[i];
1.212 christos 316: newerror = (*execsw[i]->es_makecmds)(l, epp);
1.243.2.1 ad 317:
318: if (!newerror) {
319: /* Seems ok: check that entry point is sane */
320: if (epp->ep_entry > VM_MAXUSER_ADDRESS) {
321: error = ENOEXEC;
322: break;
323: }
324:
325: /* check limits */
326: if ((epp->ep_tsize > MAXTSIZ) ||
327: (epp->ep_dsize > (u_quad_t)l->l_proc->p_rlimit
328: [RLIMIT_DATA].rlim_cur)) {
329: error = ENOMEM;
330: break;
331: }
332: return 0;
333: }
334:
335: if (epp->ep_emul_root != NULL) {
336: vrele(epp->ep_emul_root);
337: epp->ep_emul_root = NULL;
338: }
339: if (epp->ep_interp != NULL) {
340: vrele(epp->ep_interp);
341: epp->ep_interp = NULL;
342: }
343:
1.68 cgd 344: /* make sure the first "interesting" error code is saved. */
1.243.2.1 ad 345: if (error == ENOEXEC)
1.68 cgd 346: error = newerror;
1.124 jdolecek 347:
1.243.2.1 ad 348: if (epp->ep_flags & EXEC_DESTR)
349: /* Error from "#!" code, tidied up by recursive call */
1.55 cgd 350: return error;
351: }
352:
353: /*
354: * free any vmspace-creation commands,
355: * and release their references
356: */
357: kill_vmcmds(&epp->ep_vmcmds);
358:
359: bad2:
360: /*
1.99 wrstuden 361: * close and release the vnode, restore the old one, free the
1.55 cgd 362: * pathname buf, and punt.
363: */
1.99 wrstuden 364: vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.223 ad 365: VOP_CLOSE(vp, FREAD, l->l_cred, l);
1.99 wrstuden 366: vput(vp);
1.120 thorpej 367: PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
1.55 cgd 368: return error;
369:
370: bad1:
371: /*
372: * free the namei pathname buffer, and put the vnode
373: * (which we don't yet have open).
374: */
1.77 cgd 375: vput(vp); /* was still locked */
1.120 thorpej 376: PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
1.55 cgd 377: return error;
378: }
379:
1.188 chs 380: #ifdef __MACHINE_STACK_GROWS_UP
381: #define STACK_PTHREADSPACE NBPG
382: #else
383: #define STACK_PTHREADSPACE 0
384: #endif
385:
1.204 cube 386: static int
387: execve_fetch_element(char * const *array, size_t index, char **value)
388: {
389: return copyin(array + index, value, sizeof(*value));
390: }
391:
1.55 cgd 392: /*
393: * exec system call
394: */
395: /* ARGSUSED */
1.75 christos 396: int
1.231 yamt 397: sys_execve(struct lwp *l, void *v, register_t *retval)
1.71 thorpej 398: {
1.108 augustss 399: struct sys_execve_args /* {
1.138 lukem 400: syscallarg(const char *) path;
401: syscallarg(char * const *) argp;
402: syscallarg(char * const *) envp;
1.71 thorpej 403: } */ *uap = v;
1.204 cube 404:
405: return execve1(l, SCARG(uap, path), SCARG(uap, argp),
406: SCARG(uap, envp), execve_fetch_element);
407: }
408:
409: int
410: execve1(struct lwp *l, const char *path, char * const *args,
411: char * const *envs, execve_fetch_element_t fetch_element)
412: {
1.153 thorpej 413: int error;
414: u_int i;
1.138 lukem 415: struct exec_package pack;
416: struct nameidata nid;
417: struct vattr attr;
1.164 thorpej 418: struct proc *p;
1.138 lukem 419: char *argp;
420: char *dp, *sp;
421: long argc, envc;
422: size_t len;
423: char *stack;
424: struct ps_strings arginfo;
1.213 manu 425: struct ps_strings *aip = &arginfo;
1.138 lukem 426: struct vmspace *vm;
427: char **tmpfap;
428: int szsigcode;
429: struct exec_vmcmd *base_vcp;
1.237 ad 430: ksiginfo_t ksi;
431: ksiginfoq_t kq;
1.200 elad 432: #ifdef SYSTRACE
1.238 pavel 433: int wassugid = ISSET(p->p_flag, PK_SUGID);
1.200 elad 434: char pathbuf[MAXPATHLEN];
435: size_t pathbuflen;
436: #endif /* SYSTRACE */
1.55 cgd 437:
1.237 ad 438: p = l->l_proc;
1.164 thorpej 439:
1.149 christos 440: /*
1.237 ad 441: * Drain existing references and forbid new ones. The process
442: * should be left alone until we're done here. This is necessary
443: * to avoid race conditions - e.g. in ptrace() - that might allow
444: * a local user to illicitly obtain elevated privileges.
445: */
446: mutex_enter(&p->p_mutex);
447: proc_drainrefs(p);
448: mutex_exit(&p->p_mutex);
1.149 christos 449:
1.138 lukem 450: base_vcp = NULL;
1.55 cgd 451: /*
1.129 jdolecek 452: * Init the namei data to point the file user's program name.
453: * This is done here rather than in check_exec(), so that it's
454: * possible to override this settings if any of makecmd/probe
455: * functions call check_exec() recursively - for example,
456: * see exec_script_makecmds().
457: */
1.200 elad 458: #ifdef SYSTRACE
1.238 pavel 459: if (ISSET(p->p_flag, PK_SYSTRACE))
1.201 elad 460: systrace_execve0(p);
461:
1.204 cube 462: error = copyinstr(path, pathbuf, sizeof(pathbuf),
1.200 elad 463: &pathbuflen);
464: if (error)
465: goto clrflg;
466:
1.243.2.1 ad 467: NDINIT(&nid, LOOKUP, NOFOLLOW | TRYEMULROOT, UIO_SYSSPACE, pathbuf, l);
1.200 elad 468: #else
1.243.2.1 ad 469: NDINIT(&nid, LOOKUP, NOFOLLOW | TRYEMULROOT, UIO_USERSPACE, path, l);
1.200 elad 470: #endif /* SYSTRACE */
1.55 cgd 471:
472: /*
473: * initialize the fields of the exec package.
474: */
1.200 elad 475: #ifdef SYSTRACE
476: pack.ep_name = pathbuf;
477: #else
1.204 cube 478: pack.ep_name = path;
1.200 elad 479: #endif /* SYSTRACE */
1.119 thorpej 480: pack.ep_hdr = malloc(exec_maxhdrsz, M_EXEC, M_WAITOK);
1.55 cgd 481: pack.ep_hdrlen = exec_maxhdrsz;
482: pack.ep_hdrvalid = 0;
483: pack.ep_ndp = &nid;
1.67 christos 484: pack.ep_emul_arg = NULL;
1.55 cgd 485: pack.ep_vmcmds.evs_cnt = 0;
486: pack.ep_vmcmds.evs_used = 0;
487: pack.ep_vap = &attr;
488: pack.ep_flags = 0;
1.243.2.1 ad 489: pack.ep_emul_root = NULL;
490: pack.ep_interp = NULL;
491: pack.ep_esch = NULL;
1.55 cgd 492:
1.147 jdolecek 493: #ifdef LKM
1.237 ad 494: rw_enter(&exec_lock, RW_READER);
1.147 jdolecek 495: #endif
1.130 jdolecek 496:
1.55 cgd 497: /* see if we can run it. */
1.233 elad 498: if ((error = check_exec(l, &pack)) != 0)
1.55 cgd 499: goto freehdr;
500:
501: /* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */
502:
503: /* allocate an argument buffer */
1.196 yamt 504: argp = (char *) uvm_km_alloc(exec_map, NCARGS, 0,
505: UVM_KMF_PAGEABLE|UVM_KMF_WAITVA);
1.55 cgd 506: #ifdef DIAGNOSTIC
1.208 junyoung 507: if (argp == NULL)
1.55 cgd 508: panic("execve: argp == NULL");
509: #endif
510: dp = argp;
511: argc = 0;
512:
513: /* copy the fake args list, if there's one, freeing it as we go */
514: if (pack.ep_flags & EXEC_HASARGL) {
515: tmpfap = pack.ep_fa;
516: while (*tmpfap != NULL) {
517: char *cp;
518:
519: cp = *tmpfap;
520: while (*cp)
521: *dp++ = *cp++;
1.74 christos 522: dp++;
1.55 cgd 523:
524: FREE(*tmpfap, M_EXEC);
525: tmpfap++; argc++;
526: }
527: FREE(pack.ep_fa, M_EXEC);
528: pack.ep_flags &= ~EXEC_HASARGL;
529: }
530:
531: /* Now get argv & environment */
1.204 cube 532: if (args == NULL) {
1.55 cgd 533: error = EINVAL;
534: goto bad;
535: }
1.204 cube 536: /* 'i' will index the argp/envp element to be retrieved */
537: i = 0;
1.55 cgd 538: if (pack.ep_flags & EXEC_SKIPARG)
1.204 cube 539: i++;
1.55 cgd 540:
541: while (1) {
542: len = argp + ARG_MAX - dp;
1.204 cube 543: if ((error = (*fetch_element)(args, i, &sp)) != 0)
1.55 cgd 544: goto bad;
545: if (!sp)
546: break;
1.74 christos 547: if ((error = copyinstr(sp, dp, len, &len)) != 0) {
1.55 cgd 548: if (error == ENAMETOOLONG)
549: error = E2BIG;
550: goto bad;
551: }
1.243.2.2! ad 552: ktrexecarg(dp, len - 1);
1.55 cgd 553: dp += len;
1.204 cube 554: i++;
1.55 cgd 555: argc++;
556: }
557:
558: envc = 0;
1.74 christos 559: /* environment need not be there */
1.204 cube 560: if (envs != NULL) {
561: i = 0;
1.55 cgd 562: while (1) {
563: len = argp + ARG_MAX - dp;
1.204 cube 564: if ((error = (*fetch_element)(envs, i, &sp)) != 0)
1.55 cgd 565: goto bad;
566: if (!sp)
567: break;
1.74 christos 568: if ((error = copyinstr(sp, dp, len, &len)) != 0) {
1.55 cgd 569: if (error == ENAMETOOLONG)
570: error = E2BIG;
571: goto bad;
572: }
1.243.2.2! ad 573: ktrexecenv(dp, len - 1);
1.55 cgd 574: dp += len;
1.204 cube 575: i++;
1.55 cgd 576: envc++;
577: }
578: }
1.61 mycroft 579:
580: dp = (char *) ALIGN(dp);
1.55 cgd 581:
1.243.2.1 ad 582: szsigcode = pack.ep_esch->es_emul->e_esigcode -
583: pack.ep_esch->es_emul->e_sigcode;
1.65 fvdl 584:
1.55 cgd 585: /* Now check if args & environ fit into new stack */
1.105 eeh 586: if (pack.ep_flags & EXEC_32)
1.243.2.1 ad 587: len = ((argc + envc + 2 + pack.ep_esch->es_arglen) *
1.126 mrg 588: sizeof(int) + sizeof(int) + dp + STACKGAPLEN +
1.188 chs 589: szsigcode + sizeof(struct ps_strings) + STACK_PTHREADSPACE)
590: - argp;
1.105 eeh 591: else
1.243.2.1 ad 592: len = ((argc + envc + 2 + pack.ep_esch->es_arglen) *
1.126 mrg 593: sizeof(char *) + sizeof(int) + dp + STACKGAPLEN +
1.188 chs 594: szsigcode + sizeof(struct ps_strings) + STACK_PTHREADSPACE)
595: - argp;
1.67 christos 596:
1.243 matt 597: #ifdef STACKLALIGN /* arm, etc. */
598: len = STACKALIGN(len); /* make the stack "safely" aligned */
599: #else
1.55 cgd 600: len = ALIGN(len); /* make the stack "safely" aligned */
1.243 matt 601: #endif
1.55 cgd 602:
603: if (len > pack.ep_ssize) { /* in effect, compare to initial limit */
604: error = ENOMEM;
605: goto bad;
606: }
607:
1.237 ad 608: /* Get rid of other LWPs. */
609: if (p->p_nlwps > 1) {
610: mutex_enter(&p->p_smutex);
611: exit_lwps(l);
612: mutex_exit(&p->p_smutex);
613: }
1.164 thorpej 614: KDASSERT(p->p_nlwps == 1);
615:
616: /* This is now LWP 1 */
617: l->l_lid = 1;
618: p->p_nlwpid = 1;
619:
620: /* Remove POSIX timers */
621: timers_free(p, TIMERS_POSIX);
622:
1.55 cgd 623: /* adjust "active stack depth" for process VSZ */
624: pack.ep_ssize = len; /* maybe should go elsewhere, but... */
625:
1.86 thorpej 626: /*
627: * Do whatever is necessary to prepare the address space
628: * for remapping. Note that this might replace the current
629: * vmspace with another!
630: */
1.164 thorpej 631: uvmspace_exec(l, pack.ep_vm_minaddr, pack.ep_vm_maxaddr);
1.55 cgd 632:
1.186 chs 633: /* record proc's vnode, for use by procfs and others */
634: if (p->p_textvp)
635: vrele(p->p_textvp);
636: VREF(pack.ep_vp);
637: p->p_textvp = pack.ep_vp;
638:
1.55 cgd 639: /* Now map address space */
1.86 thorpej 640: vm = p->p_vmspace;
1.241 dogcow 641: vm->vm_taddr = (void *)pack.ep_taddr;
1.55 cgd 642: vm->vm_tsize = btoc(pack.ep_tsize);
1.241 dogcow 643: vm->vm_daddr = (void*)pack.ep_daddr;
1.55 cgd 644: vm->vm_dsize = btoc(pack.ep_dsize);
645: vm->vm_ssize = btoc(pack.ep_ssize);
1.241 dogcow 646: vm->vm_maxsaddr = (void *)pack.ep_maxsaddr;
647: vm->vm_minsaddr = (void *)pack.ep_minsaddr;
1.55 cgd 648:
649: /* create the new process's VM space by running the vmcmds */
650: #ifdef DIAGNOSTIC
651: if (pack.ep_vmcmds.evs_used == 0)
652: panic("execve: no vmcmds");
653: #endif
654: for (i = 0; i < pack.ep_vmcmds.evs_used && !error; i++) {
655: struct exec_vmcmd *vcp;
656:
657: vcp = &pack.ep_vmcmds.evs_cmds[i];
1.114 matt 658: if (vcp->ev_flags & VMCMD_RELATIVE) {
659: #ifdef DIAGNOSTIC
660: if (base_vcp == NULL)
661: panic("execve: relative vmcmd with no base");
662: if (vcp->ev_flags & VMCMD_BASE)
663: panic("execve: illegal base & relative vmcmd");
664: #endif
665: vcp->ev_addr += base_vcp->ev_addr;
666: }
1.212 christos 667: error = (*vcp->ev_proc)(l, vcp);
1.143 christos 668: #ifdef DEBUG_EXEC
1.111 matt 669: if (error) {
1.143 christos 670: int j;
671: struct exec_vmcmd *vp = &pack.ep_vmcmds.evs_cmds[0];
672: for (j = 0; j <= i; j++)
673: uprintf(
674: "vmcmd[%d] = %#lx/%#lx fd@%#lx prot=0%o flags=%d\n",
675: j, vp[j].ev_addr, vp[j].ev_len,
676: vp[j].ev_offset, vp[j].ev_prot,
677: vp[j].ev_flags);
1.111 matt 678: }
1.143 christos 679: #endif /* DEBUG_EXEC */
1.114 matt 680: if (vcp->ev_flags & VMCMD_BASE)
681: base_vcp = vcp;
1.55 cgd 682: }
683:
684: /* free the vmspace-creation commands, and release their references */
685: kill_vmcmds(&pack.ep_vmcmds);
686:
1.186 chs 687: vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
1.223 ad 688: VOP_CLOSE(pack.ep_vp, FREAD, l->l_cred, l);
1.186 chs 689: vput(pack.ep_vp);
690:
1.55 cgd 691: /* if an error happened, deallocate and punt */
1.111 matt 692: if (error) {
1.143 christos 693: DPRINTF(("execve: vmcmd %i failed: %d\n", i - 1, error));
1.55 cgd 694: goto exec_abort;
1.111 matt 695: }
1.55 cgd 696:
697: /* remember information about the process */
698: arginfo.ps_nargvstr = argc;
699: arginfo.ps_nenvstr = envc;
700:
1.163 chs 701: stack = (char *)STACK_ALLOC(STACK_GROW(vm->vm_minsaddr,
1.188 chs 702: STACK_PTHREADSPACE + sizeof(struct ps_strings) + szsigcode),
1.163 chs 703: len - (sizeof(struct ps_strings) + szsigcode));
704: #ifdef __MACHINE_STACK_GROWS_UP
705: /*
706: * The copyargs call always copies into lower addresses
707: * first, moving towards higher addresses, starting with
1.183 junyoung 708: * the stack pointer that we give. When the stack grows
709: * down, this puts argc/argv/envp very shallow on the
710: * stack, right at the first user stack pointer, and puts
1.163 chs 711: * STACKGAPLEN very deep in the stack. When the stack
712: * grows up, the situation is reversed.
713: *
714: * Normally, this is no big deal. But the ld_elf.so _rtld()
1.183 junyoung 715: * function expects to be called with a single pointer to
716: * a region that has a few words it can stash values into,
1.163 chs 717: * followed by argc/argv/envp. When the stack grows down,
718: * it's easy to decrement the stack pointer a little bit to
719: * allocate the space for these few words and pass the new
720: * stack pointer to _rtld. When the stack grows up, however,
1.171 chs 721: * a few words before argc is part of the signal trampoline, XXX
1.163 chs 722: * so we have a problem.
723: *
1.183 junyoung 724: * Instead of changing how _rtld works, we take the easy way
725: * out and steal 32 bytes before we call copyargs. This
1.163 chs 726: * space is effectively stolen from STACKGAPLEN.
727: */
728: stack += 32;
729: #endif /* __MACHINE_STACK_GROWS_UP */
730:
1.55 cgd 731: /* Now copy argc, args & environ to new stack */
1.243.2.1 ad 732: error = (*pack.ep_esch->es_copyargs)(l, &pack, &arginfo, &stack, argp);
1.144 christos 733: if (error) {
734: DPRINTF(("execve: copyargs failed %d\n", error));
1.55 cgd 735: goto exec_abort;
1.111 matt 736: }
1.144 christos 737: /* Move the stack back to original point */
1.163 chs 738: stack = (char *)STACK_GROW(vm->vm_minsaddr, len);
1.55 cgd 739:
1.121 eeh 740: /* fill process ps_strings info */
1.188 chs 741: p->p_psstr = (struct ps_strings *)
742: STACK_ALLOC(STACK_GROW(vm->vm_minsaddr, STACK_PTHREADSPACE),
1.163 chs 743: sizeof(struct ps_strings));
1.121 eeh 744: p->p_psargv = offsetof(struct ps_strings, ps_argvstr);
745: p->p_psnargv = offsetof(struct ps_strings, ps_nargvstr);
746: p->p_psenv = offsetof(struct ps_strings, ps_envstr);
747: p->p_psnenv = offsetof(struct ps_strings, ps_nenvstr);
748:
1.55 cgd 749: /* copy out the process's ps_strings structure */
1.213 manu 750: if ((error = copyout(aip, (char *)p->p_psstr,
1.144 christos 751: sizeof(arginfo))) != 0) {
1.143 christos 752: DPRINTF(("execve: ps_strings copyout %p->%p size %ld failed\n",
1.213 manu 753: aip, (char *)p->p_psstr, (long)sizeof(arginfo)));
1.55 cgd 754: goto exec_abort;
1.111 matt 755: }
1.109 simonb 756:
1.212 christos 757: fdcloseexec(l); /* handle close on exec */
1.55 cgd 758: execsigs(p); /* reset catched signals */
1.183 junyoung 759:
1.164 thorpej 760: l->l_ctxlink = NULL; /* reset ucontext link */
1.55 cgd 761:
762: /* set command name & other accounting info */
763: len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);
1.94 perry 764: memcpy(p->p_comm, nid.ni_cnd.cn_nameptr, len);
1.55 cgd 765: p->p_comm[len] = 0;
766: p->p_acflag &= ~AFORK;
767:
1.238 pavel 768: p->p_flag |= PK_EXEC;
1.237 ad 769:
770: /*
771: * Stop profiling.
772: */
773: if ((p->p_stflag & PST_PROFIL) != 0) {
774: mutex_spin_enter(&p->p_stmutex);
775: stopprofclock(p);
776: mutex_spin_exit(&p->p_stmutex);
777: }
778:
779: /*
780: * It's OK to test PS_PPWAIT unlocked here, as other LWPs have
781: * exited and exec()/exit() are the only places it will be cleared.
782: */
783: if ((p->p_sflag & PS_PPWAIT) != 0) {
1.242 ad 784: mutex_enter(&proclist_lock);
1.237 ad 785: mutex_enter(&p->p_smutex);
786: p->p_sflag &= ~PS_PPWAIT;
787: cv_broadcast(&p->p_pptr->p_waitcv);
788: mutex_exit(&p->p_smutex);
1.242 ad 789: mutex_exit(&proclist_lock);
1.55 cgd 790: }
791:
792: /*
1.237 ad 793: * Deal with set[ug]id. MNT_NOSUID has already been used to disable
794: * s[ug]id. It's OK to check for PSL_TRACED here as we have blocked
795: * out additional references on the process for the moment.
1.55 cgd 796: */
1.237 ad 797: if ((p->p_slflag & PSL_TRACED) == 0 &&
1.141 thorpej 798:
799: (((attr.va_mode & S_ISUID) != 0 &&
1.221 ad 800: kauth_cred_geteuid(l->l_cred) != attr.va_uid) ||
1.141 thorpej 801:
802: ((attr.va_mode & S_ISGID) != 0 &&
1.221 ad 803: kauth_cred_getegid(l->l_cred) != attr.va_gid))) {
1.141 thorpej 804: /*
805: * Mark the process as SUGID before we do
806: * anything that might block.
807: */
1.237 ad 808: proc_crmod_enter();
1.240 thorpej 809: proc_crmod_leave(NULL, NULL, true);
1.152 christos 810:
811: /* Make sure file descriptors 0..2 are in use. */
1.212 christos 812: if ((error = fdcheckstd(l)) != 0) {
1.209 christos 813: DPRINTF(("execve: fdcheckstd failed %d\n", error));
1.152 christos 814: goto exec_abort;
1.209 christos 815: }
1.141 thorpej 816:
1.220 ad 817: /*
818: * Copy the credential so other references don't see our
819: * changes.
820: */
1.221 ad 821: l->l_cred = kauth_cred_copy(l->l_cred);
1.55 cgd 822: #ifdef KTRACE
823: /*
824: * If process is being ktraced, turn off - unless
825: * root set it.
826: */
1.237 ad 827: if (p->p_tracep) {
1.243.2.2! ad 828: mutex_enter(&ktrace_lock);
1.237 ad 829: if (!(p->p_traceflag & KTRFAC_ROOT))
830: ktrderef(p);
1.243.2.2! ad 831: mutex_exit(&ktrace_lock);
1.237 ad 832: }
1.55 cgd 833: #endif
1.83 mycroft 834: if (attr.va_mode & S_ISUID)
1.221 ad 835: kauth_cred_seteuid(l->l_cred, attr.va_uid);
1.83 mycroft 836: if (attr.va_mode & S_ISGID)
1.221 ad 837: kauth_cred_setegid(l->l_cred, attr.va_gid);
1.210 christos 838: } else {
1.221 ad 839: if (kauth_cred_geteuid(l->l_cred) ==
840: kauth_cred_getuid(l->l_cred) &&
841: kauth_cred_getegid(l->l_cred) ==
842: kauth_cred_getgid(l->l_cred))
1.238 pavel 843: p->p_flag &= ~PK_SUGID;
1.210 christos 844: }
1.220 ad 845:
846: /*
847: * Copy the credential so other references don't see our changes.
848: * Test to see if this is necessary first, since in the common case
849: * we won't need a private reference.
850: */
1.221 ad 851: if (kauth_cred_geteuid(l->l_cred) != kauth_cred_getsvuid(l->l_cred) ||
852: kauth_cred_getegid(l->l_cred) != kauth_cred_getsvgid(l->l_cred)) {
853: l->l_cred = kauth_cred_copy(l->l_cred);
854: kauth_cred_setsvuid(l->l_cred, kauth_cred_geteuid(l->l_cred));
855: kauth_cred_setsvgid(l->l_cred, kauth_cred_getegid(l->l_cred));
1.220 ad 856: }
1.155 gmcgarry 857:
1.221 ad 858: /* Update the master credentials. */
1.227 ad 859: if (l->l_cred != p->p_cred) {
860: kauth_cred_t ocred;
861:
862: kauth_cred_hold(l->l_cred);
1.237 ad 863: mutex_enter(&p->p_mutex);
1.227 ad 864: ocred = p->p_cred;
865: p->p_cred = l->l_cred;
1.237 ad 866: mutex_exit(&p->p_mutex);
1.227 ad 867: kauth_cred_free(ocred);
868: }
1.221 ad 869:
1.155 gmcgarry 870: #if defined(__HAVE_RAS)
871: /*
872: * Remove all RASs from the address space.
873: */
874: ras_purgeall(p);
875: #endif
1.107 fvdl 876:
877: doexechooks(p);
1.55 cgd 878:
1.196 yamt 879: uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE);
1.55 cgd 880:
1.120 thorpej 881: PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
1.159 jdolecek 882:
883: /* notify others that we exec'd */
884: KNOTE(&p->p_klist, NOTE_EXEC);
1.55 cgd 885:
886: /* setup new registers and do misc. setup. */
1.243.2.1 ad 887: (*pack.ep_esch->es_emul->e_setregs)(l, &pack, (u_long) stack);
888: if (pack.ep_esch->es_setregs)
889: (*pack.ep_esch->es_setregs)(l, &pack, (u_long) stack);
1.55 cgd 890:
1.171 chs 891: /* map the process's signal trampoline code */
1.243.2.1 ad 892: if (exec_sigcode_map(p, pack.ep_esch->es_emul)) {
1.209 christos 893: DPRINTF(("execve: map sigcode failed %d\n", error));
1.171 chs 894: goto exec_abort;
1.209 christos 895: }
1.171 chs 896:
1.122 jdolecek 897: free(pack.ep_hdr, M_EXEC);
898:
1.243.2.1 ad 899: /* The emulation root will usually have been found when we looked
900: * for the elf interpreter (or similar), if not look now. */
901: if (pack.ep_esch->es_emul->e_path != NULL && pack.ep_emul_root == NULL)
902: emul_find_root(l, &pack);
903:
904: /* Any old emulation root got removed by fdcloseexec */
905: p->p_cwdi->cwdi_edir = pack.ep_emul_root;
906: pack.ep_emul_root = NULL;
907: if (pack.ep_interp != NULL)
908: vrele(pack.ep_interp);
909:
1.122 jdolecek 910: /*
1.194 peter 911: * Call emulation specific exec hook. This can setup per-process
1.122 jdolecek 912: * p->p_emuldata or do any other per-process stuff an emulation needs.
913: *
914: * If we are executing process of different emulation than the
915: * original forked process, call e_proc_exit() of the old emulation
916: * first, then e_proc_exec() of new emulation. If the emulation is
917: * same, the exec hook code should deallocate any old emulation
918: * resources held previously by this process.
919: */
1.124 jdolecek 920: if (p->p_emul && p->p_emul->e_proc_exit
1.243.2.1 ad 921: && p->p_emul != pack.ep_esch->es_emul)
1.122 jdolecek 922: (*p->p_emul->e_proc_exit)(p);
923:
1.123 jdolecek 924: /*
925: * Call exec hook. Emulation code may NOT store reference to anything
926: * from &pack.
927: */
1.243.2.1 ad 928: if (pack.ep_esch->es_emul->e_proc_exec)
929: (*pack.ep_esch->es_emul->e_proc_exec)(p, &pack);
1.122 jdolecek 930:
931: /* update p_emul, the old value is no longer needed */
1.243.2.1 ad 932: p->p_emul = pack.ep_esch->es_emul;
1.148 thorpej 933:
934: /* ...and the same for p_execsw */
1.243.2.1 ad 935: p->p_execsw = pack.ep_esch;
1.148 thorpej 936:
1.133 mycroft 937: #ifdef __HAVE_SYSCALL_INTERN
938: (*p->p_emul->e_syscall_intern)(p);
939: #endif
1.243.2.2! ad 940: ktremul();
1.85 mycroft 941:
1.147 jdolecek 942: #ifdef LKM
1.237 ad 943: rw_exit(&exec_lock);
1.147 jdolecek 944: #endif
1.162 manu 945:
1.237 ad 946: mutex_enter(&proclist_mutex);
947:
948: if ((p->p_slflag & (PSL_TRACED|PSL_SYSCALL)) == PSL_TRACED) {
949: KSI_INIT_EMPTY(&ksi);
950: ksi.ksi_signo = SIGTRAP;
951: ksi.ksi_lid = l->l_lid;
952: kpsignal(p, &ksi, NULL);
953: }
1.162 manu 954:
1.237 ad 955: if (p->p_sflag & PS_STOPEXEC) {
956: KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
1.175 dsl 957: p->p_pptr->p_nstopchild++;
1.237 ad 958: p->p_pptr->p_waited = 0;
959: mutex_enter(&p->p_smutex);
960: ksiginfo_queue_init(&kq);
961: sigclearall(p, &contsigmask, &kq);
962: lwp_lock(l);
963: p->p_refcnt = 1;
964: l->l_stat = LSSTOP;
1.162 manu 965: p->p_stat = SSTOP;
1.164 thorpej 966: p->p_nrlwps--;
1.237 ad 967: mutex_exit(&p->p_smutex);
968: mutex_exit(&proclist_mutex);
1.243.2.1 ad 969: mi_switch(l);
1.237 ad 970: ksiginfo_queue_drain(&kq);
971: KERNEL_LOCK(l->l_biglocks, l);
972: } else {
973: mutex_exit(&proclist_mutex);
974:
975: /* Unlock the process. */
976: mb_write();
977: p->p_refcnt = 1;
1.162 manu 978: }
979:
1.200 elad 980: #ifdef SYSTRACE
1.237 ad 981: /* XXXSMP */
1.238 pavel 982: if (ISSET(p->p_flag, PK_SYSTRACE) &&
983: wassugid && !ISSET(p->p_flag, PK_SUGID))
1.201 elad 984: systrace_execve1(pathbuf, p);
1.200 elad 985: #endif /* SYSTRACE */
986:
1.85 mycroft 987: return (EJUSTRETURN);
1.55 cgd 988:
1.138 lukem 989: bad:
1.55 cgd 990: /* free the vmspace-creation commands, and release their references */
991: kill_vmcmds(&pack.ep_vmcmds);
992: /* kill any opened file descriptor, if necessary */
993: if (pack.ep_flags & EXEC_HASFD) {
994: pack.ep_flags &= ~EXEC_HASFD;
1.212 christos 995: (void) fdrelease(l, pack.ep_fd);
1.55 cgd 996: }
997: /* close and put the exec'd file */
1.99 wrstuden 998: vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
1.223 ad 999: VOP_CLOSE(pack.ep_vp, FREAD, l->l_cred, l);
1.99 wrstuden 1000: vput(pack.ep_vp);
1.120 thorpej 1001: PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
1.196 yamt 1002: uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE);
1.55 cgd 1003:
1.138 lukem 1004: freehdr:
1.200 elad 1005: free(pack.ep_hdr, M_EXEC);
1.243.2.1 ad 1006: if (pack.ep_emul_root != NULL)
1007: vrele(pack.ep_emul_root);
1008: if (pack.ep_interp != NULL)
1009: vrele(pack.ep_interp);
1.200 elad 1010:
1011: #ifdef SYSTRACE
1012: clrflg:
1013: #endif /* SYSTRACE */
1.237 ad 1014: /* Unlock the process. */
1015: mb_write();
1016: p->p_refcnt = 1;
1017:
1.147 jdolecek 1018: #ifdef LKM
1.237 ad 1019: rw_exit(&exec_lock);
1.147 jdolecek 1020: #endif
1.130 jdolecek 1021:
1.55 cgd 1022: return error;
1023:
1.138 lukem 1024: exec_abort:
1.147 jdolecek 1025: #ifdef LKM
1.237 ad 1026: rw_exit(&exec_lock);
1.147 jdolecek 1027: #endif
1.130 jdolecek 1028:
1.55 cgd 1029: /*
1030: * the old process doesn't exist anymore. exit gracefully.
1031: * get rid of the (new) address space we have created, if any, get rid
1032: * of our namei data and vnode, and exit noting failure
1033: */
1.88 mrg 1034: uvm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,
1035: VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);
1.73 mycroft 1036: if (pack.ep_emul_arg)
1.124 jdolecek 1037: FREE(pack.ep_emul_arg, M_TEMP);
1.120 thorpej 1038: PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
1.196 yamt 1039: uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE);
1.119 thorpej 1040: free(pack.ep_hdr, M_EXEC);
1.243.2.1 ad 1041: if (pack.ep_emul_root != NULL)
1042: vrele(pack.ep_emul_root);
1043: if (pack.ep_interp != NULL)
1044: vrele(pack.ep_interp);
1.237 ad 1045:
1046: /*
1047: * Acquire the sched-state mutex (exit1() will release it). Since
1048: * this is a failed exec and we are exiting, keep the process locked
1049: * (p->p_refcnt == 0) through exit1().
1050: */
1051: mutex_enter(&p->p_smutex);
1.164 thorpej 1052: exit1(l, W_EXITCODE(error, SIGABRT));
1.55 cgd 1053:
1054: /* NOTREACHED */
1055: return 0;
1.67 christos 1056: }
1057:
1058:
1.144 christos 1059: int
1.231 yamt 1060: copyargs(struct lwp *l, struct exec_package *pack, struct ps_strings *arginfo,
1061: char **stackp, void *argp)
1.67 christos 1062: {
1.138 lukem 1063: char **cpp, *dp, *sp;
1064: size_t len;
1065: void *nullp;
1066: long argc, envc;
1.144 christos 1067: int error;
1.138 lukem 1068:
1.144 christos 1069: cpp = (char **)*stackp;
1.138 lukem 1070: nullp = NULL;
1071: argc = arginfo->ps_nargvstr;
1072: envc = arginfo->ps_nenvstr;
1.144 christos 1073: if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0)
1074: return error;
1.67 christos 1075:
1.243.2.1 ad 1076: dp = (char *) (cpp + argc + envc + 2 + pack->ep_esch->es_arglen);
1.67 christos 1077: sp = argp;
1078:
1079: /* XXX don't copy them out, remap them! */
1.69 mycroft 1080: arginfo->ps_argvstr = cpp; /* remember location of argv for later */
1.67 christos 1081:
1082: for (; --argc >= 0; sp += len, dp += len)
1.144 christos 1083: if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
1084: (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
1085: return error;
1.67 christos 1086:
1.144 christos 1087: if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
1088: return error;
1.67 christos 1089:
1.69 mycroft 1090: arginfo->ps_envstr = cpp; /* remember location of envp for later */
1.67 christos 1091:
1092: for (; --envc >= 0; sp += len, dp += len)
1.144 christos 1093: if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
1094: (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
1095: return error;
1.67 christos 1096:
1.144 christos 1097: if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
1098: return error;
1.67 christos 1099:
1.144 christos 1100: *stackp = (char *)cpp;
1101: return 0;
1.55 cgd 1102: }
1.130 jdolecek 1103:
1104: #ifdef LKM
1105: /*
1106: * Find an emulation of given name in list of emulations.
1.151 jdolecek 1107: * Needs to be called with the exec_lock held.
1.130 jdolecek 1108: */
1.151 jdolecek 1109: const struct emul *
1.138 lukem 1110: emul_search(const char *name)
1.130 jdolecek 1111: {
1112: struct emul_entry *it;
1113:
1114: LIST_FOREACH(it, &el_head, el_list) {
1115: if (strcmp(name, it->el_emul->e_name) == 0)
1116: return it->el_emul;
1117: }
1118:
1119: return NULL;
1120: }
1121:
1122: /*
1123: * Add an emulation to list, if it's not there already.
1124: */
1125: int
1.138 lukem 1126: emul_register(const struct emul *emul, int ro_entry)
1.130 jdolecek 1127: {
1.138 lukem 1128: struct emul_entry *ee;
1129: int error;
1.130 jdolecek 1130:
1.138 lukem 1131: error = 0;
1.237 ad 1132: rw_enter(&exec_lock, RW_WRITER);
1.130 jdolecek 1133:
1134: if (emul_search(emul->e_name)) {
1135: error = EEXIST;
1136: goto out;
1137: }
1138:
1139: MALLOC(ee, struct emul_entry *, sizeof(struct emul_entry),
1140: M_EXEC, M_WAITOK);
1141: ee->el_emul = emul;
1142: ee->ro_entry = ro_entry;
1143: LIST_INSERT_HEAD(&el_head, ee, el_list);
1144:
1.138 lukem 1145: out:
1.237 ad 1146: rw_exit(&exec_lock);
1.130 jdolecek 1147: return error;
1148: }
1149:
1150: /*
1151: * Remove emulation with name 'name' from list of supported emulations.
1152: */
1153: int
1.138 lukem 1154: emul_unregister(const char *name)
1.130 jdolecek 1155: {
1156: const struct proclist_desc *pd;
1.138 lukem 1157: struct emul_entry *it;
1158: int i, error;
1159: struct proc *ptmp;
1.130 jdolecek 1160:
1.138 lukem 1161: error = 0;
1.237 ad 1162: rw_enter(&exec_lock, RW_WRITER);
1.130 jdolecek 1163:
1164: LIST_FOREACH(it, &el_head, el_list) {
1165: if (strcmp(it->el_emul->e_name, name) == 0)
1166: break;
1167: }
1168:
1169: if (!it) {
1170: error = ENOENT;
1171: goto out;
1172: }
1173:
1174: if (it->ro_entry) {
1175: error = EBUSY;
1176: goto out;
1177: }
1178:
1179: /* test if any execw[] entry is still using this */
1.132 jdolecek 1180: for(i=0; i < nexecs; i++) {
1.130 jdolecek 1181: if (execsw[i]->es_emul == it->el_emul) {
1182: error = EBUSY;
1183: goto out;
1184: }
1185: }
1186:
1187: /*
1188: * Test if any process is running under this emulation - since
1189: * emul_unregister() is running quite sendomly, it's better
1190: * to do expensive check here than to use any locking.
1191: */
1.242 ad 1192: mutex_enter(&proclist_lock);
1.130 jdolecek 1193: for (pd = proclists; pd->pd_list != NULL && !error; pd++) {
1.191 yamt 1194: PROCLIST_FOREACH(ptmp, pd->pd_list) {
1.130 jdolecek 1195: if (ptmp->p_emul == it->el_emul) {
1196: error = EBUSY;
1197: break;
1198: }
1199: }
1200: }
1.242 ad 1201: mutex_exit(&proclist_lock);
1.183 junyoung 1202:
1.130 jdolecek 1203: if (error)
1204: goto out;
1205:
1.183 junyoung 1206:
1.130 jdolecek 1207: /* entry is not used, remove it */
1208: LIST_REMOVE(it, el_list);
1209: FREE(it, M_EXEC);
1210:
1.138 lukem 1211: out:
1.237 ad 1212: rw_exit(&exec_lock);
1.130 jdolecek 1213: return error;
1214: }
1215:
1216: /*
1217: * Add execsw[] entry.
1218: */
1219: int
1.138 lukem 1220: exec_add(struct execsw *esp, const char *e_name)
1.130 jdolecek 1221: {
1.138 lukem 1222: struct exec_entry *it;
1223: int error;
1.130 jdolecek 1224:
1.138 lukem 1225: error = 0;
1.237 ad 1226: rw_enter(&exec_lock, RW_WRITER);
1.130 jdolecek 1227:
1228: if (!esp->es_emul) {
1229: esp->es_emul = emul_search(e_name);
1230: if (!esp->es_emul) {
1231: error = ENOENT;
1232: goto out;
1233: }
1234: }
1235:
1236: LIST_FOREACH(it, &ex_head, ex_list) {
1237: /* assume tuple (makecmds, probe_func, emulation) is unique */
1.182 junyoung 1238: if (it->es->es_makecmds == esp->es_makecmds
1.130 jdolecek 1239: && it->es->u.elf_probe_func == esp->u.elf_probe_func
1240: && it->es->es_emul == esp->es_emul) {
1241: error = EEXIST;
1242: goto out;
1243: }
1244: }
1245:
1246: /* if we got here, the entry doesn't exist yet */
1247: MALLOC(it, struct exec_entry *, sizeof(struct exec_entry),
1248: M_EXEC, M_WAITOK);
1249: it->es = esp;
1250: LIST_INSERT_HEAD(&ex_head, it, ex_list);
1251:
1252: /* update execsw[] */
1253: exec_init(0);
1254:
1.138 lukem 1255: out:
1.237 ad 1256: rw_exit(&exec_lock);
1.130 jdolecek 1257: return error;
1258: }
1259:
1260: /*
1261: * Remove execsw[] entry.
1262: */
1263: int
1.138 lukem 1264: exec_remove(const struct execsw *esp)
1.130 jdolecek 1265: {
1.138 lukem 1266: struct exec_entry *it;
1267: int error;
1.130 jdolecek 1268:
1.138 lukem 1269: error = 0;
1.237 ad 1270: rw_enter(&exec_lock, RW_WRITER);
1.130 jdolecek 1271:
1272: LIST_FOREACH(it, &ex_head, ex_list) {
1273: /* assume tuple (makecmds, probe_func, emulation) is unique */
1.182 junyoung 1274: if (it->es->es_makecmds == esp->es_makecmds
1.130 jdolecek 1275: && it->es->u.elf_probe_func == esp->u.elf_probe_func
1276: && it->es->es_emul == esp->es_emul)
1277: break;
1278: }
1279: if (!it) {
1280: error = ENOENT;
1281: goto out;
1282: }
1283:
1284: /* remove item from list and free resources */
1285: LIST_REMOVE(it, ex_list);
1286: FREE(it, M_EXEC);
1287:
1288: /* update execsw[] */
1289: exec_init(0);
1290:
1.138 lukem 1291: out:
1.237 ad 1292: rw_exit(&exec_lock);
1.130 jdolecek 1293: return error;
1294: }
1295:
1296: static void
1.138 lukem 1297: link_es(struct execsw_entry **listp, const struct execsw *esp)
1.130 jdolecek 1298: {
1299: struct execsw_entry *et, *e1;
1300:
1.215 matt 1301: et = (struct execsw_entry *) malloc(sizeof(struct execsw_entry),
1.130 jdolecek 1302: M_TEMP, M_WAITOK);
1303: et->next = NULL;
1304: et->es = esp;
1305: if (*listp == NULL) {
1306: *listp = et;
1307: return;
1308: }
1309:
1310: switch(et->es->es_prio) {
1311: case EXECSW_PRIO_FIRST:
1312: /* put new entry as the first */
1313: et->next = *listp;
1314: *listp = et;
1315: break;
1316: case EXECSW_PRIO_ANY:
1317: /* put new entry after all *_FIRST and *_ANY entries */
1318: for(e1 = *listp; e1->next
1319: && e1->next->es->es_prio != EXECSW_PRIO_LAST;
1320: e1 = e1->next);
1321: et->next = e1->next;
1322: e1->next = et;
1323: break;
1324: case EXECSW_PRIO_LAST:
1325: /* put new entry as the last one */
1326: for(e1 = *listp; e1->next; e1 = e1->next);
1327: e1->next = et;
1328: break;
1329: default:
1330: #ifdef DIAGNOSTIC
1.157 provos 1331: panic("execw[] entry with unknown priority %d found",
1.130 jdolecek 1332: et->es->es_prio);
1.217 elad 1333: #else
1334: free(et, M_TEMP);
1.130 jdolecek 1335: #endif
1336: break;
1337: }
1338: }
1339:
1340: /*
1341: * Initialize exec structures. If init_boot is true, also does necessary
1342: * one-time initialization (it's called from main() that way).
1.147 jdolecek 1343: * Once system is multiuser, this should be called with exec_lock held,
1.130 jdolecek 1344: * i.e. via exec_{add|remove}().
1345: */
1346: int
1.138 lukem 1347: exec_init(int init_boot)
1.130 jdolecek 1348: {
1.138 lukem 1349: const struct execsw **new_es, * const *old_es;
1350: struct execsw_entry *list, *e1;
1351: struct exec_entry *e2;
1352: int i, es_sz;
1.130 jdolecek 1353:
1354: if (init_boot) {
1355: /* do one-time initializations */
1.237 ad 1356: rw_init(&exec_lock);
1.130 jdolecek 1357:
1358: /* register compiled-in emulations */
1359: for(i=0; i < nexecs_builtin; i++) {
1360: if (execsw_builtin[i].es_emul)
1361: emul_register(execsw_builtin[i].es_emul, 1);
1362: }
1363: #ifdef DIAGNOSTIC
1364: if (i == 0)
1.157 provos 1365: panic("no emulations found in execsw_builtin[]");
1.130 jdolecek 1366: #endif
1367: }
1368:
1369: /*
1370: * Build execsw[] array from builtin entries and entries added
1371: * at runtime.
1372: */
1373: list = NULL;
1374: for(i=0; i < nexecs_builtin; i++)
1375: link_es(&list, &execsw_builtin[i]);
1376:
1377: /* Add dynamically loaded entries */
1378: es_sz = nexecs_builtin;
1379: LIST_FOREACH(e2, &ex_head, ex_list) {
1380: link_es(&list, e2->es);
1381: es_sz++;
1382: }
1.183 junyoung 1383:
1.130 jdolecek 1384: /*
1385: * Now that we have sorted all execw entries, create new execsw[]
1386: * and free no longer needed memory in the process.
1387: */
1388: new_es = malloc(es_sz * sizeof(struct execsw *), M_EXEC, M_WAITOK);
1389: for(i=0; list; i++) {
1390: new_es[i] = list->es;
1391: e1 = list->next;
1.215 matt 1392: free(list, M_TEMP);
1.130 jdolecek 1393: list = e1;
1394: }
1395:
1396: /*
1397: * New execsw[] array built, now replace old execsw[] and free
1398: * used memory.
1399: */
1400: old_es = execsw;
1401: execsw = new_es;
1402: nexecs = es_sz;
1403: if (old_es)
1.198 christos 1404: /*XXXUNCONST*/
1405: free(__UNCONST(old_es), M_EXEC);
1.130 jdolecek 1406:
1407: /*
1408: * Figure out the maximum size of an exec header.
1.183 junyoung 1409: */
1.130 jdolecek 1410: exec_maxhdrsz = 0;
1411: for (i = 0; i < nexecs; i++) {
1412: if (execsw[i]->es_hdrsz > exec_maxhdrsz)
1413: exec_maxhdrsz = execsw[i]->es_hdrsz;
1414: }
1415:
1416: return 0;
1417: }
1418: #endif
1419:
1420: #ifndef LKM
1421: /*
1422: * Simplified exec_init() for kernels without LKMs. Only initialize
1423: * exec_maxhdrsz and execsw[].
1424: */
1425: int
1.138 lukem 1426: exec_init(int init_boot)
1.130 jdolecek 1427: {
1428: int i;
1429:
1430: #ifdef DIAGNOSTIC
1431: if (!init_boot)
1432: panic("exec_init(): called with init_boot == 0");
1433: #endif
1434:
1435: /* do one-time initializations */
1436: nexecs = nexecs_builtin;
1437: execsw = malloc(nexecs*sizeof(struct execsw *), M_EXEC, M_WAITOK);
1438:
1439: /*
1440: * Fill in execsw[] and figure out the maximum size of an exec header.
1441: */
1442: exec_maxhdrsz = 0;
1443: for(i=0; i < nexecs; i++) {
1444: execsw[i] = &execsw_builtin[i];
1445: if (execsw_builtin[i].es_hdrsz > exec_maxhdrsz)
1446: exec_maxhdrsz = execsw_builtin[i].es_hdrsz;
1447: }
1448:
1449: return 0;
1450:
1451: }
1452: #endif /* !LKM */
1.171 chs 1453:
1454: static int
1455: exec_sigcode_map(struct proc *p, const struct emul *e)
1456: {
1457: vaddr_t va;
1458: vsize_t sz;
1459: int error;
1460: struct uvm_object *uobj;
1461:
1.184 drochner 1462: sz = (vaddr_t)e->e_esigcode - (vaddr_t)e->e_sigcode;
1463:
1464: if (e->e_sigobject == NULL || sz == 0) {
1.171 chs 1465: return 0;
1466: }
1467:
1468: /*
1469: * If we don't have a sigobject for this emulation, create one.
1470: *
1471: * sigobject is an anonymous memory object (just like SYSV shared
1472: * memory) that we keep a permanent reference to and that we map
1473: * in all processes that need this sigcode. The creation is simple,
1474: * we create an object, add a permanent reference to it, map it in
1475: * kernel space, copy out the sigcode to it and unmap it.
1.189 jdolecek 1476: * We map it with PROT_READ|PROT_EXEC into the process just
1477: * the way sys_mmap() would map it.
1.171 chs 1478: */
1479:
1480: uobj = *e->e_sigobject;
1481: if (uobj == NULL) {
1482: uobj = uao_create(sz, 0);
1.181 christos 1483: (*uobj->pgops->pgo_reference)(uobj);
1.171 chs 1484: va = vm_map_min(kernel_map);
1485: if ((error = uvm_map(kernel_map, &va, round_page(sz),
1486: uobj, 0, 0,
1487: UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
1488: UVM_INH_SHARE, UVM_ADV_RANDOM, 0)))) {
1489: printf("kernel mapping failed %d\n", error);
1490: (*uobj->pgops->pgo_detach)(uobj);
1491: return (error);
1492: }
1493: memcpy((void *)va, e->e_sigcode, sz);
1494: #ifdef PMAP_NEED_PROCWR
1495: pmap_procwr(&proc0, va, sz);
1496: #endif
1497: uvm_unmap(kernel_map, va, va + round_page(sz));
1498: *e->e_sigobject = uobj;
1499: }
1500:
1.172 enami 1501: /* Just a hint to uvm_map where to put it. */
1.195 fvdl 1502: va = e->e_vm_default_addr(p, (vaddr_t)p->p_vmspace->vm_daddr,
1503: round_page(sz));
1.187 chs 1504:
1505: #ifdef __alpha__
1506: /*
1507: * Tru64 puts /sbin/loader at the end of user virtual memory,
1508: * which causes the above calculation to put the sigcode at
1509: * an invalid address. Put it just below the text instead.
1510: */
1.193 jmc 1511: if (va == (vaddr_t)vm_map_max(&p->p_vmspace->vm_map)) {
1.187 chs 1512: va = (vaddr_t)p->p_vmspace->vm_taddr - round_page(sz);
1513: }
1514: #endif
1515:
1.171 chs 1516: (*uobj->pgops->pgo_reference)(uobj);
1517: error = uvm_map(&p->p_vmspace->vm_map, &va, round_page(sz),
1518: uobj, 0, 0,
1519: UVM_MAPFLAG(UVM_PROT_RX, UVM_PROT_RX, UVM_INH_SHARE,
1520: UVM_ADV_RANDOM, 0));
1521: if (error) {
1522: (*uobj->pgops->pgo_detach)(uobj);
1523: return (error);
1524: }
1525: p->p_sigctx.ps_sigcode = (void *)va;
1526: return (0);
1527: }
CVSweb <webmaster@jp.NetBSD.org>