Annotation of src/sys/kern/kern_exec.c, Revision 1.196
1.196 ! yamt 1: /* $NetBSD$ */
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.196 ! yamt 36: __KERNEL_RCSID(0, "$NetBSD$");
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.55 cgd 41:
42: #include <sys/param.h>
43: #include <sys/systm.h>
44: #include <sys/filedesc.h>
45: #include <sys/kernel.h>
46: #include <sys/proc.h>
47: #include <sys/mount.h>
48: #include <sys/malloc.h>
49: #include <sys/namei.h>
50: #include <sys/vnode.h>
51: #include <sys/file.h>
52: #include <sys/acct.h>
53: #include <sys/exec.h>
54: #include <sys/ktrace.h>
55: #include <sys/resourcevar.h>
56: #include <sys/wait.h>
57: #include <sys/mman.h>
1.155 gmcgarry 58: #include <sys/ras.h>
1.55 cgd 59: #include <sys/signalvar.h>
60: #include <sys/stat.h>
1.124 jdolecek 61: #include <sys/syscall.h>
1.55 cgd 62:
1.164 thorpej 63: #include <sys/sa.h>
64: #include <sys/savar.h>
1.56 cgd 65: #include <sys/syscallargs.h>
1.55 cgd 66:
1.88 mrg 67: #include <uvm/uvm_extern.h>
68:
1.55 cgd 69: #include <machine/cpu.h>
70: #include <machine/reg.h>
71:
1.171 chs 72: static int exec_sigcode_map(struct proc *, const struct emul *);
73:
1.143 christos 74: #ifdef DEBUG_EXEC
75: #define DPRINTF(a) uprintf a
76: #else
77: #define DPRINTF(a)
78: #endif /* DEBUG_EXEC */
1.165 thorpej 79:
80: MALLOC_DEFINE(M_EXEC, "exec", "argument lists & other mem used by exec");
1.143 christos 81:
1.130 jdolecek 82: /*
83: * Exec function switch:
84: *
85: * Note that each makecmds function is responsible for loading the
86: * exec package with the necessary functions for any exec-type-specific
87: * handling.
88: *
89: * Functions for specific exec types should be defined in their own
90: * header file.
91: */
1.138 lukem 92: extern const struct execsw execsw_builtin[];
93: extern int nexecs_builtin;
94: static const struct execsw **execsw = NULL;
95: static int nexecs;
96:
1.153 thorpej 97: u_int exec_maxhdrsz; /* must not be static - netbsd32 needs it */
1.130 jdolecek 98:
99: #ifdef LKM
100: /* list of supported emulations */
101: static
102: LIST_HEAD(emlist_head, emul_entry) el_head = LIST_HEAD_INITIALIZER(el_head);
103: struct emul_entry {
1.138 lukem 104: LIST_ENTRY(emul_entry) el_list;
105: const struct emul *el_emul;
106: int ro_entry;
1.130 jdolecek 107: };
108:
109: /* list of dynamically loaded execsw entries */
110: static
111: LIST_HEAD(execlist_head, exec_entry) ex_head = LIST_HEAD_INITIALIZER(ex_head);
112: struct exec_entry {
1.138 lukem 113: LIST_ENTRY(exec_entry) ex_list;
114: const struct execsw *es;
1.130 jdolecek 115: };
116:
117: /* structure used for building execw[] */
118: struct execsw_entry {
1.138 lukem 119: struct execsw_entry *next;
120: const struct execsw *es;
1.130 jdolecek 121: };
122: #endif /* LKM */
123:
1.124 jdolecek 124: #ifdef SYSCALL_DEBUG
125: extern const char * const syscallnames[];
126: #endif
1.133 mycroft 127: #ifdef __HAVE_SYSCALL_INTERN
1.138 lukem 128: void syscall_intern(struct proc *);
1.133 mycroft 129: #else
1.138 lukem 130: void syscall(void);
1.133 mycroft 131: #endif
1.124 jdolecek 132:
1.185 drochner 133: #ifdef COMPAT_16
1.173 christos 134: extern char sigcode[], esigcode[];
1.171 chs 135: struct uvm_object *emul_netbsd_object;
1.173 christos 136: #endif
1.171 chs 137:
1.173 christos 138: /* NetBSD emul struct */
1.124 jdolecek 139: const struct emul emul_netbsd = {
140: "netbsd",
1.127 jdolecek 141: NULL, /* emulation path */
1.133 mycroft 142: #ifndef __HAVE_MINIMAL_EMUL
1.140 manu 143: EMUL_HAS_SYS___syscall,
1.124 jdolecek 144: NULL,
145: SYS_syscall,
1.161 jdolecek 146: SYS_NSYSENT,
1.133 mycroft 147: #endif
1.124 jdolecek 148: sysent,
149: #ifdef SYSCALL_DEBUG
150: syscallnames,
151: #else
152: NULL,
153: #endif
1.133 mycroft 154: sendsig,
1.142 christos 155: trapsignal,
1.180 fvdl 156: NULL,
1.185 drochner 157: #ifdef COMPAT_16
1.124 jdolecek 158: sigcode,
159: esigcode,
1.171 chs 160: &emul_netbsd_object,
1.173 christos 161: #else
162: NULL,
163: NULL,
164: NULL,
165: #endif
1.145 jdolecek 166: setregs,
1.128 jdolecek 167: NULL,
168: NULL,
169: NULL,
1.179 manu 170: NULL,
171: NULL,
1.133 mycroft 172: #ifdef __HAVE_SYSCALL_INTERN
173: syscall_intern,
174: #else
175: syscall,
176: #endif
1.156 manu 177: NULL,
178: NULL,
1.195 fvdl 179:
180: uvm_default_mapaddr,
1.124 jdolecek 181: };
182:
1.147 jdolecek 183: #ifdef LKM
1.55 cgd 184: /*
1.130 jdolecek 185: * Exec lock. Used to control access to execsw[] structures.
186: * This must not be static so that netbsd32 can access it, too.
187: */
188: struct lock exec_lock;
1.183 junyoung 189:
1.138 lukem 190: static void link_es(struct execsw_entry **, const struct execsw *);
1.130 jdolecek 191: #endif /* LKM */
192:
193: /*
1.55 cgd 194: * check exec:
195: * given an "executable" described in the exec package's namei info,
196: * see what we can do with it.
197: *
198: * ON ENTRY:
199: * exec package with appropriate namei info
200: * proc pointer of exec'ing proc
1.160 blymn 201: * iff verified exec enabled then flag indicating a direct exec or
202: * an indirect exec (i.e. for a shell script interpreter)
1.55 cgd 203: * NO SELF-LOCKED VNODES
204: *
205: * ON EXIT:
206: * error: nothing held, etc. exec header still allocated.
1.77 cgd 207: * ok: filled exec package, executable's vnode (unlocked).
1.55 cgd 208: *
209: * EXEC SWITCH ENTRY:
210: * Locked vnode to check, exec package, proc.
211: *
212: * EXEC SWITCH EXIT:
1.77 cgd 213: * ok: return 0, filled exec package, executable's vnode (unlocked).
1.55 cgd 214: * error: destructive:
215: * everything deallocated execept exec header.
1.76 cgd 216: * non-destructive:
1.77 cgd 217: * error code, executable's vnode (unlocked),
1.76 cgd 218: * exec header unmodified.
1.55 cgd 219: */
220: int
1.160 blymn 221: #ifdef VERIFIED_EXEC
1.169 fvdl 222: check_exec(struct proc *p, struct exec_package *epp, int direct_exec)
1.183 junyoung 223: #else
1.169 fvdl 224: check_exec(struct proc *p, struct exec_package *epp)
1.160 blymn 225: #endif
1.55 cgd 226: {
1.138 lukem 227: int error, i;
228: struct vnode *vp;
1.55 cgd 229: struct nameidata *ndp;
1.138 lukem 230: size_t resid;
1.55 cgd 231:
232: ndp = epp->ep_ndp;
233: ndp->ni_cnd.cn_nameiop = LOOKUP;
234: ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | SAVENAME;
235: /* first get the vnode */
1.74 christos 236: if ((error = namei(ndp)) != 0)
1.55 cgd 237: return error;
238: epp->ep_vp = vp = ndp->ni_vp;
239:
1.84 mycroft 240: /* check access and type */
1.55 cgd 241: if (vp->v_type != VREG) {
1.81 kleink 242: error = EACCES;
1.55 cgd 243: goto bad1;
244: }
1.169 fvdl 245: if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0)
1.84 mycroft 246: goto bad1;
1.55 cgd 247:
248: /* get attributes */
1.169 fvdl 249: if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0)
1.55 cgd 250: goto bad1;
251:
252: /* Check mount point */
253: if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
254: error = EACCES;
255: goto bad1;
256: }
1.141 thorpej 257: if (vp->v_mount->mnt_flag & MNT_NOSUID)
1.83 mycroft 258: epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
1.55 cgd 259:
260: /* try to open it */
1.169 fvdl 261: if ((error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) != 0)
1.55 cgd 262: goto bad1;
263:
1.99 wrstuden 264: /* unlock vp, since we need it unlocked from here on out. */
1.90 fvdl 265: VOP_UNLOCK(vp, 0);
1.77 cgd 266:
1.183 junyoung 267:
1.160 blymn 268: #ifdef VERIFIED_EXEC
269: /* Evaluate signature for file... */
270: if ((error = check_veriexec(p, vp, epp, direct_exec)) != 0)
271: goto bad2;
272: #endif
273:
1.55 cgd 274: /* now we have the file, get the exec header */
1.125 chs 275: uvn_attach(vp, VM_PROT_READ);
1.74 christos 276: error = vn_rdwr(UIO_READ, vp, epp->ep_hdr, epp->ep_hdrlen, 0,
1.190 skrll 277: UIO_SYSSPACE, 0, p->p_ucred, &resid, NULL);
1.74 christos 278: if (error)
1.55 cgd 279: goto bad2;
280: epp->ep_hdrvalid = epp->ep_hdrlen - resid;
281:
282: /*
1.136 eeh 283: * Set up default address space limits. Can be overridden
284: * by individual exec packages.
1.183 junyoung 285: *
1.167 manu 286: * XXX probably should be all done in the exec pakages.
1.136 eeh 287: */
288: epp->ep_vm_minaddr = VM_MIN_ADDRESS;
289: epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS;
290: /*
1.55 cgd 291: * set up the vmcmds for creation of the process
292: * address space
293: */
294: error = ENOEXEC;
295: for (i = 0; i < nexecs && error != 0; i++) {
1.68 cgd 296: int newerror;
297:
1.130 jdolecek 298: epp->ep_esch = execsw[i];
1.182 junyoung 299: newerror = (*execsw[i]->es_makecmds)(p, epp);
1.68 cgd 300: /* make sure the first "interesting" error code is saved. */
301: if (!newerror || error == ENOEXEC)
302: error = newerror;
1.124 jdolecek 303:
1.182 junyoung 304: /* if es_makecmds call was successful, update epp->ep_es */
1.124 jdolecek 305: if (!newerror && (epp->ep_flags & EXEC_HASES) == 0)
1.130 jdolecek 306: epp->ep_es = execsw[i];
1.124 jdolecek 307:
1.55 cgd 308: if (epp->ep_flags & EXEC_DESTR && error != 0)
309: return error;
310: }
311: if (!error) {
312: /* check that entry point is sane */
313: if (epp->ep_entry > VM_MAXUSER_ADDRESS)
314: error = ENOEXEC;
315:
316: /* check limits */
317: if ((epp->ep_tsize > MAXTSIZ) ||
1.153 thorpej 318: (epp->ep_dsize >
319: (u_quad_t)p->p_rlimit[RLIMIT_DATA].rlim_cur))
1.55 cgd 320: error = ENOMEM;
321:
322: if (!error)
323: return (0);
324: }
325:
326: /*
327: * free any vmspace-creation commands,
328: * and release their references
329: */
330: kill_vmcmds(&epp->ep_vmcmds);
331:
332: bad2:
333: /*
1.99 wrstuden 334: * close and release the vnode, restore the old one, free the
1.55 cgd 335: * pathname buf, and punt.
336: */
1.99 wrstuden 337: vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.169 fvdl 338: VOP_CLOSE(vp, FREAD, p->p_ucred, p);
1.99 wrstuden 339: vput(vp);
1.120 thorpej 340: PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
1.55 cgd 341: return error;
342:
343: bad1:
344: /*
345: * free the namei pathname buffer, and put the vnode
346: * (which we don't yet have open).
347: */
1.77 cgd 348: vput(vp); /* was still locked */
1.120 thorpej 349: PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
1.55 cgd 350: return error;
351: }
352:
1.188 chs 353: #ifdef __MACHINE_STACK_GROWS_UP
354: #define STACK_PTHREADSPACE NBPG
355: #else
356: #define STACK_PTHREADSPACE 0
357: #endif
358:
1.55 cgd 359: /*
360: * exec system call
361: */
362: /* ARGSUSED */
1.75 christos 363: int
1.164 thorpej 364: sys_execve(struct lwp *l, void *v, register_t *retval)
1.71 thorpej 365: {
1.108 augustss 366: struct sys_execve_args /* {
1.138 lukem 367: syscallarg(const char *) path;
368: syscallarg(char * const *) argp;
369: syscallarg(char * const *) envp;
1.71 thorpej 370: } */ *uap = v;
1.153 thorpej 371: int error;
372: u_int i;
1.138 lukem 373: struct exec_package pack;
374: struct nameidata nid;
375: struct vattr attr;
1.164 thorpej 376: struct proc *p;
1.138 lukem 377: struct ucred *cred;
378: char *argp;
379: char * const *cpp;
380: char *dp, *sp;
381: long argc, envc;
382: size_t len;
383: char *stack;
384: struct ps_strings arginfo;
385: struct vmspace *vm;
386: char **tmpfap;
387: int szsigcode;
388: struct exec_vmcmd *base_vcp;
1.164 thorpej 389: int oldlwpflags;
1.55 cgd 390:
1.164 thorpej 391: /* Disable scheduler activation upcalls. */
392: oldlwpflags = l->l_flag & (L_SA | L_SA_UPCALL);
393: if (l->l_flag & L_SA)
394: l->l_flag &= ~(L_SA | L_SA_UPCALL);
395:
396: p = l->l_proc;
1.149 christos 397: /*
398: * Lock the process and set the P_INEXEC flag to indicate that
399: * it should be left alone until we're done here. This is
400: * necessary to avoid race conditions - e.g. in ptrace() -
401: * that might allow a local user to illicitly obtain elevated
402: * privileges.
403: */
404: p->p_flag |= P_INEXEC;
405:
1.138 lukem 406: cred = p->p_ucred;
407: base_vcp = NULL;
1.55 cgd 408: /*
1.129 jdolecek 409: * Init the namei data to point the file user's program name.
410: * This is done here rather than in check_exec(), so that it's
411: * possible to override this settings if any of makecmd/probe
412: * functions call check_exec() recursively - for example,
413: * see exec_script_makecmds().
414: */
1.169 fvdl 415: NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
1.55 cgd 416:
417: /*
418: * initialize the fields of the exec package.
419: */
1.56 cgd 420: pack.ep_name = SCARG(uap, path);
1.119 thorpej 421: pack.ep_hdr = malloc(exec_maxhdrsz, M_EXEC, M_WAITOK);
1.55 cgd 422: pack.ep_hdrlen = exec_maxhdrsz;
423: pack.ep_hdrvalid = 0;
424: pack.ep_ndp = &nid;
1.67 christos 425: pack.ep_emul_arg = NULL;
1.55 cgd 426: pack.ep_vmcmds.evs_cnt = 0;
427: pack.ep_vmcmds.evs_used = 0;
428: pack.ep_vap = &attr;
429: pack.ep_flags = 0;
430:
1.147 jdolecek 431: #ifdef LKM
1.130 jdolecek 432: lockmgr(&exec_lock, LK_SHARED, NULL);
1.147 jdolecek 433: #endif
1.130 jdolecek 434:
1.55 cgd 435: /* see if we can run it. */
1.160 blymn 436: #ifdef VERIFIED_EXEC
1.169 fvdl 437: if ((error = check_exec(p, &pack, 1)) != 0)
438: /* if ((error = check_exec(p, &pack, 0)) != 0) */
1.183 junyoung 439: #else
1.169 fvdl 440: if ((error = check_exec(p, &pack)) != 0)
1.160 blymn 441: #endif
1.55 cgd 442: goto freehdr;
443:
444: /* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */
445:
446: /* allocate an argument buffer */
1.196 ! yamt 447: argp = (char *) uvm_km_alloc(exec_map, NCARGS, 0,
! 448: UVM_KMF_PAGEABLE|UVM_KMF_WAITVA);
1.55 cgd 449: #ifdef DIAGNOSTIC
1.95 eeh 450: if (argp == (vaddr_t) 0)
1.55 cgd 451: panic("execve: argp == NULL");
452: #endif
453: dp = argp;
454: argc = 0;
455:
456: /* copy the fake args list, if there's one, freeing it as we go */
457: if (pack.ep_flags & EXEC_HASARGL) {
458: tmpfap = pack.ep_fa;
459: while (*tmpfap != NULL) {
460: char *cp;
461:
462: cp = *tmpfap;
463: while (*cp)
464: *dp++ = *cp++;
1.74 christos 465: dp++;
1.55 cgd 466:
467: FREE(*tmpfap, M_EXEC);
468: tmpfap++; argc++;
469: }
470: FREE(pack.ep_fa, M_EXEC);
471: pack.ep_flags &= ~EXEC_HASARGL;
472: }
473:
474: /* Now get argv & environment */
1.56 cgd 475: if (!(cpp = SCARG(uap, argp))) {
1.55 cgd 476: error = EINVAL;
477: goto bad;
478: }
479:
480: if (pack.ep_flags & EXEC_SKIPARG)
481: cpp++;
482:
483: while (1) {
484: len = argp + ARG_MAX - dp;
1.74 christos 485: if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
1.55 cgd 486: goto bad;
487: if (!sp)
488: break;
1.74 christos 489: if ((error = copyinstr(sp, dp, len, &len)) != 0) {
1.55 cgd 490: if (error == ENAMETOOLONG)
491: error = E2BIG;
492: goto bad;
493: }
1.170 dsl 494: #ifdef KTRACE
495: if (KTRPOINT(p, KTR_EXEC_ARG))
496: ktrkmem(p, KTR_EXEC_ARG, dp, len - 1);
497: #endif
1.55 cgd 498: dp += len;
499: cpp++;
500: argc++;
501: }
502:
503: envc = 0;
1.74 christos 504: /* environment need not be there */
505: if ((cpp = SCARG(uap, envp)) != NULL ) {
1.55 cgd 506: while (1) {
507: len = argp + ARG_MAX - dp;
1.74 christos 508: if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
1.55 cgd 509: goto bad;
510: if (!sp)
511: break;
1.74 christos 512: if ((error = copyinstr(sp, dp, len, &len)) != 0) {
1.55 cgd 513: if (error == ENAMETOOLONG)
514: error = E2BIG;
515: goto bad;
516: }
1.170 dsl 517: #ifdef KTRACE
518: if (KTRPOINT(p, KTR_EXEC_ENV))
519: ktrkmem(p, KTR_EXEC_ENV, dp, len - 1);
520: #endif
1.55 cgd 521: dp += len;
522: cpp++;
523: envc++;
524: }
525: }
1.61 mycroft 526:
527: dp = (char *) ALIGN(dp);
1.55 cgd 528:
1.126 mrg 529: szsigcode = pack.ep_es->es_emul->e_esigcode -
530: pack.ep_es->es_emul->e_sigcode;
1.65 fvdl 531:
1.55 cgd 532: /* Now check if args & environ fit into new stack */
1.105 eeh 533: if (pack.ep_flags & EXEC_32)
1.126 mrg 534: len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
535: sizeof(int) + sizeof(int) + dp + STACKGAPLEN +
1.188 chs 536: szsigcode + sizeof(struct ps_strings) + STACK_PTHREADSPACE)
537: - argp;
1.105 eeh 538: else
1.126 mrg 539: len = ((argc + envc + 2 + pack.ep_es->es_arglen) *
540: sizeof(char *) + sizeof(int) + dp + STACKGAPLEN +
1.188 chs 541: szsigcode + sizeof(struct ps_strings) + STACK_PTHREADSPACE)
542: - argp;
1.67 christos 543:
1.55 cgd 544: len = ALIGN(len); /* make the stack "safely" aligned */
545:
546: if (len > pack.ep_ssize) { /* in effect, compare to initial limit */
547: error = ENOMEM;
548: goto bad;
549: }
550:
1.164 thorpej 551: /* Get rid of other LWPs/ */
552: p->p_flag |= P_WEXIT; /* XXX hack. lwp-exit stuff wants to see it. */
553: exit_lwps(l);
554: p->p_flag &= ~P_WEXIT;
555: KDASSERT(p->p_nlwps == 1);
556:
557: /* This is now LWP 1 */
558: l->l_lid = 1;
559: p->p_nlwpid = 1;
560:
561: /* Release any SA state. */
1.176 cl 562: if (p->p_sa)
563: sa_release(p);
1.164 thorpej 564:
565: /* Remove POSIX timers */
566: timers_free(p, TIMERS_POSIX);
567:
1.55 cgd 568: /* adjust "active stack depth" for process VSZ */
569: pack.ep_ssize = len; /* maybe should go elsewhere, but... */
570:
1.86 thorpej 571: /*
572: * Do whatever is necessary to prepare the address space
573: * for remapping. Note that this might replace the current
574: * vmspace with another!
575: */
1.164 thorpej 576: uvmspace_exec(l, pack.ep_vm_minaddr, pack.ep_vm_maxaddr);
1.55 cgd 577:
1.186 chs 578: /* record proc's vnode, for use by procfs and others */
579: if (p->p_textvp)
580: vrele(p->p_textvp);
581: VREF(pack.ep_vp);
582: p->p_textvp = pack.ep_vp;
583:
1.55 cgd 584: /* Now map address space */
1.86 thorpej 585: vm = p->p_vmspace;
1.158 junyoung 586: vm->vm_taddr = (caddr_t) pack.ep_taddr;
1.55 cgd 587: vm->vm_tsize = btoc(pack.ep_tsize);
1.158 junyoung 588: vm->vm_daddr = (caddr_t) pack.ep_daddr;
1.55 cgd 589: vm->vm_dsize = btoc(pack.ep_dsize);
590: vm->vm_ssize = btoc(pack.ep_ssize);
1.158 junyoung 591: vm->vm_maxsaddr = (caddr_t) pack.ep_maxsaddr;
592: vm->vm_minsaddr = (caddr_t) pack.ep_minsaddr;
1.55 cgd 593:
594: /* create the new process's VM space by running the vmcmds */
595: #ifdef DIAGNOSTIC
596: if (pack.ep_vmcmds.evs_used == 0)
597: panic("execve: no vmcmds");
598: #endif
599: for (i = 0; i < pack.ep_vmcmds.evs_used && !error; i++) {
600: struct exec_vmcmd *vcp;
601:
602: vcp = &pack.ep_vmcmds.evs_cmds[i];
1.114 matt 603: if (vcp->ev_flags & VMCMD_RELATIVE) {
604: #ifdef DIAGNOSTIC
605: if (base_vcp == NULL)
606: panic("execve: relative vmcmd with no base");
607: if (vcp->ev_flags & VMCMD_BASE)
608: panic("execve: illegal base & relative vmcmd");
609: #endif
610: vcp->ev_addr += base_vcp->ev_addr;
611: }
1.169 fvdl 612: error = (*vcp->ev_proc)(p, vcp);
1.143 christos 613: #ifdef DEBUG_EXEC
1.111 matt 614: if (error) {
1.143 christos 615: int j;
616: struct exec_vmcmd *vp = &pack.ep_vmcmds.evs_cmds[0];
617: for (j = 0; j <= i; j++)
618: uprintf(
619: "vmcmd[%d] = %#lx/%#lx fd@%#lx prot=0%o flags=%d\n",
620: j, vp[j].ev_addr, vp[j].ev_len,
621: vp[j].ev_offset, vp[j].ev_prot,
622: vp[j].ev_flags);
1.111 matt 623: }
1.143 christos 624: #endif /* DEBUG_EXEC */
1.114 matt 625: if (vcp->ev_flags & VMCMD_BASE)
626: base_vcp = vcp;
1.55 cgd 627: }
628:
629: /* free the vmspace-creation commands, and release their references */
630: kill_vmcmds(&pack.ep_vmcmds);
631:
1.186 chs 632: vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
633: VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
634: vput(pack.ep_vp);
635:
1.55 cgd 636: /* if an error happened, deallocate and punt */
1.111 matt 637: if (error) {
1.143 christos 638: DPRINTF(("execve: vmcmd %i failed: %d\n", i - 1, error));
1.55 cgd 639: goto exec_abort;
1.111 matt 640: }
1.55 cgd 641:
642: /* remember information about the process */
643: arginfo.ps_nargvstr = argc;
644: arginfo.ps_nenvstr = envc;
645:
1.163 chs 646: stack = (char *)STACK_ALLOC(STACK_GROW(vm->vm_minsaddr,
1.188 chs 647: STACK_PTHREADSPACE + sizeof(struct ps_strings) + szsigcode),
1.163 chs 648: len - (sizeof(struct ps_strings) + szsigcode));
649: #ifdef __MACHINE_STACK_GROWS_UP
650: /*
651: * The copyargs call always copies into lower addresses
652: * first, moving towards higher addresses, starting with
1.183 junyoung 653: * the stack pointer that we give. When the stack grows
654: * down, this puts argc/argv/envp very shallow on the
655: * stack, right at the first user stack pointer, and puts
1.163 chs 656: * STACKGAPLEN very deep in the stack. When the stack
657: * grows up, the situation is reversed.
658: *
659: * Normally, this is no big deal. But the ld_elf.so _rtld()
1.183 junyoung 660: * function expects to be called with a single pointer to
661: * a region that has a few words it can stash values into,
1.163 chs 662: * followed by argc/argv/envp. When the stack grows down,
663: * it's easy to decrement the stack pointer a little bit to
664: * allocate the space for these few words and pass the new
665: * stack pointer to _rtld. When the stack grows up, however,
1.171 chs 666: * a few words before argc is part of the signal trampoline, XXX
1.163 chs 667: * so we have a problem.
668: *
1.183 junyoung 669: * Instead of changing how _rtld works, we take the easy way
670: * out and steal 32 bytes before we call copyargs. This
1.163 chs 671: * space is effectively stolen from STACKGAPLEN.
672: */
673: stack += 32;
674: #endif /* __MACHINE_STACK_GROWS_UP */
675:
1.55 cgd 676: /* Now copy argc, args & environ to new stack */
1.169 fvdl 677: error = (*pack.ep_es->es_copyargs)(p, &pack, &arginfo, &stack, argp);
1.144 christos 678: if (error) {
679: DPRINTF(("execve: copyargs failed %d\n", error));
1.55 cgd 680: goto exec_abort;
1.111 matt 681: }
1.144 christos 682: /* Move the stack back to original point */
1.163 chs 683: stack = (char *)STACK_GROW(vm->vm_minsaddr, len);
1.55 cgd 684:
1.121 eeh 685: /* fill process ps_strings info */
1.188 chs 686: p->p_psstr = (struct ps_strings *)
687: STACK_ALLOC(STACK_GROW(vm->vm_minsaddr, STACK_PTHREADSPACE),
1.163 chs 688: sizeof(struct ps_strings));
1.121 eeh 689: p->p_psargv = offsetof(struct ps_strings, ps_argvstr);
690: p->p_psnargv = offsetof(struct ps_strings, ps_nargvstr);
691: p->p_psenv = offsetof(struct ps_strings, ps_envstr);
692: p->p_psnenv = offsetof(struct ps_strings, ps_nenvstr);
693:
1.55 cgd 694: /* copy out the process's ps_strings structure */
1.144 christos 695: if ((error = copyout(&arginfo, (char *)p->p_psstr,
696: sizeof(arginfo))) != 0) {
1.143 christos 697: DPRINTF(("execve: ps_strings copyout %p->%p size %ld failed\n",
698: &arginfo, (char *)p->p_psstr, (long)sizeof(arginfo)));
1.55 cgd 699: goto exec_abort;
1.111 matt 700: }
1.109 simonb 701:
1.102 ross 702: stopprofclock(p); /* stop profiling */
1.169 fvdl 703: fdcloseexec(p); /* handle close on exec */
1.55 cgd 704: execsigs(p); /* reset catched signals */
1.183 junyoung 705:
1.164 thorpej 706: l->l_ctxlink = NULL; /* reset ucontext link */
1.55 cgd 707:
708: /* set command name & other accounting info */
709: len = min(nid.ni_cnd.cn_namelen, MAXCOMLEN);
1.94 perry 710: memcpy(p->p_comm, nid.ni_cnd.cn_nameptr, len);
1.55 cgd 711: p->p_comm[len] = 0;
712: p->p_acflag &= ~AFORK;
713:
714: p->p_flag |= P_EXEC;
715: if (p->p_flag & P_PPWAIT) {
716: p->p_flag &= ~P_PPWAIT;
717: wakeup((caddr_t) p->p_pptr);
718: }
719:
720: /*
721: * deal with set[ug]id.
1.141 thorpej 722: * MNT_NOSUID has already been used to disable s[ug]id.
1.55 cgd 723: */
1.141 thorpej 724: if ((p->p_flag & P_TRACED) == 0 &&
725:
726: (((attr.va_mode & S_ISUID) != 0 &&
727: p->p_ucred->cr_uid != attr.va_uid) ||
728:
729: ((attr.va_mode & S_ISGID) != 0 &&
730: p->p_ucred->cr_gid != attr.va_gid))) {
731: /*
732: * Mark the process as SUGID before we do
733: * anything that might block.
734: */
735: p_sugid(p);
1.152 christos 736:
737: /* Make sure file descriptors 0..2 are in use. */
1.169 fvdl 738: if ((error = fdcheckstd(p)) != 0)
1.152 christos 739: goto exec_abort;
1.141 thorpej 740:
1.55 cgd 741: p->p_ucred = crcopy(cred);
742: #ifdef KTRACE
743: /*
744: * If process is being ktraced, turn off - unless
745: * root set it.
746: */
1.91 christos 747: if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT))
748: ktrderef(p);
1.55 cgd 749: #endif
1.83 mycroft 750: if (attr.va_mode & S_ISUID)
1.55 cgd 751: p->p_ucred->cr_uid = attr.va_uid;
1.83 mycroft 752: if (attr.va_mode & S_ISGID)
1.55 cgd 753: p->p_ucred->cr_gid = attr.va_gid;
1.79 mrg 754: } else
755: p->p_flag &= ~P_SUGID;
1.55 cgd 756: p->p_cred->p_svuid = p->p_ucred->cr_uid;
757: p->p_cred->p_svgid = p->p_ucred->cr_gid;
1.155 gmcgarry 758:
759: #if defined(__HAVE_RAS)
760: /*
761: * Remove all RASs from the address space.
762: */
763: ras_purgeall(p);
764: #endif
1.107 fvdl 765:
766: doexechooks(p);
1.55 cgd 767:
1.196 ! yamt 768: uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE);
1.55 cgd 769:
1.120 thorpej 770: PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
1.159 jdolecek 771:
772: /* notify others that we exec'd */
773: KNOTE(&p->p_klist, NOTE_EXEC);
1.55 cgd 774:
775: /* setup new registers and do misc. setup. */
1.164 thorpej 776: (*pack.ep_es->es_emul->e_setregs)(l, &pack, (u_long) stack);
1.145 jdolecek 777: if (pack.ep_es->es_setregs)
1.164 thorpej 778: (*pack.ep_es->es_setregs)(l, &pack, (u_long) stack);
1.55 cgd 779:
1.171 chs 780: /* map the process's signal trampoline code */
781: if (exec_sigcode_map(p, pack.ep_es->es_emul))
782: goto exec_abort;
783:
1.55 cgd 784: if (p->p_flag & P_TRACED)
785: psignal(p, SIGTRAP);
786:
1.122 jdolecek 787: free(pack.ep_hdr, M_EXEC);
788:
789: /*
1.194 peter 790: * Call emulation specific exec hook. This can setup per-process
1.122 jdolecek 791: * p->p_emuldata or do any other per-process stuff an emulation needs.
792: *
793: * If we are executing process of different emulation than the
794: * original forked process, call e_proc_exit() of the old emulation
795: * first, then e_proc_exec() of new emulation. If the emulation is
796: * same, the exec hook code should deallocate any old emulation
797: * resources held previously by this process.
798: */
1.124 jdolecek 799: if (p->p_emul && p->p_emul->e_proc_exit
800: && p->p_emul != pack.ep_es->es_emul)
1.122 jdolecek 801: (*p->p_emul->e_proc_exit)(p);
802:
1.123 jdolecek 803: /*
804: * Call exec hook. Emulation code may NOT store reference to anything
805: * from &pack.
806: */
1.124 jdolecek 807: if (pack.ep_es->es_emul->e_proc_exec)
808: (*pack.ep_es->es_emul->e_proc_exec)(p, &pack);
1.122 jdolecek 809:
810: /* update p_emul, the old value is no longer needed */
1.124 jdolecek 811: p->p_emul = pack.ep_es->es_emul;
1.148 thorpej 812:
813: /* ...and the same for p_execsw */
814: p->p_execsw = pack.ep_es;
815:
1.133 mycroft 816: #ifdef __HAVE_SYSCALL_INTERN
817: (*p->p_emul->e_syscall_intern)(p);
818: #endif
1.70 christos 819: #ifdef KTRACE
820: if (KTRPOINT(p, KTR_EMUL))
1.169 fvdl 821: ktremul(p);
1.70 christos 822: #endif
1.85 mycroft 823:
1.147 jdolecek 824: #ifdef LKM
1.130 jdolecek 825: lockmgr(&exec_lock, LK_RELEASE, NULL);
1.147 jdolecek 826: #endif
1.149 christos 827: p->p_flag &= ~P_INEXEC;
1.162 manu 828:
829: if (p->p_flag & P_STOPEXEC) {
830: int s;
831:
832: sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
833: SCHED_LOCK(s);
1.175 dsl 834: p->p_pptr->p_nstopchild++;
1.162 manu 835: p->p_stat = SSTOP;
1.164 thorpej 836: l->l_stat = LSSTOP;
837: p->p_nrlwps--;
838: mi_switch(l, NULL);
1.162 manu 839: SCHED_ASSERT_UNLOCKED();
840: splx(s);
841: }
842:
1.85 mycroft 843: return (EJUSTRETURN);
1.55 cgd 844:
1.138 lukem 845: bad:
1.149 christos 846: p->p_flag &= ~P_INEXEC;
1.55 cgd 847: /* free the vmspace-creation commands, and release their references */
848: kill_vmcmds(&pack.ep_vmcmds);
849: /* kill any opened file descriptor, if necessary */
850: if (pack.ep_flags & EXEC_HASFD) {
851: pack.ep_flags &= ~EXEC_HASFD;
1.169 fvdl 852: (void) fdrelease(p, pack.ep_fd);
1.55 cgd 853: }
854: /* close and put the exec'd file */
1.99 wrstuden 855: vn_lock(pack.ep_vp, LK_EXCLUSIVE | LK_RETRY);
1.169 fvdl 856: VOP_CLOSE(pack.ep_vp, FREAD, cred, p);
1.99 wrstuden 857: vput(pack.ep_vp);
1.120 thorpej 858: PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
1.196 ! yamt 859: uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE);
1.55 cgd 860:
1.138 lukem 861: freehdr:
1.164 thorpej 862: l->l_flag |= oldlwpflags;
1.150 christos 863: p->p_flag &= ~P_INEXEC;
1.147 jdolecek 864: #ifdef LKM
1.130 jdolecek 865: lockmgr(&exec_lock, LK_RELEASE, NULL);
1.147 jdolecek 866: #endif
1.130 jdolecek 867:
1.119 thorpej 868: free(pack.ep_hdr, M_EXEC);
1.55 cgd 869: return error;
870:
1.138 lukem 871: exec_abort:
1.150 christos 872: p->p_flag &= ~P_INEXEC;
1.147 jdolecek 873: #ifdef LKM
1.130 jdolecek 874: lockmgr(&exec_lock, LK_RELEASE, NULL);
1.147 jdolecek 875: #endif
1.130 jdolecek 876:
1.55 cgd 877: /*
878: * the old process doesn't exist anymore. exit gracefully.
879: * get rid of the (new) address space we have created, if any, get rid
880: * of our namei data and vnode, and exit noting failure
881: */
1.88 mrg 882: uvm_deallocate(&vm->vm_map, VM_MIN_ADDRESS,
883: VM_MAXUSER_ADDRESS - VM_MIN_ADDRESS);
1.73 mycroft 884: if (pack.ep_emul_arg)
1.124 jdolecek 885: FREE(pack.ep_emul_arg, M_TEMP);
1.120 thorpej 886: PNBUF_PUT(nid.ni_cnd.cn_pnbuf);
1.196 ! yamt 887: uvm_km_free(exec_map, (vaddr_t) argp, NCARGS, UVM_KMF_PAGEABLE);
1.119 thorpej 888: free(pack.ep_hdr, M_EXEC);
1.164 thorpej 889: exit1(l, W_EXITCODE(error, SIGABRT));
1.55 cgd 890:
891: /* NOTREACHED */
892: return 0;
1.67 christos 893: }
894:
895:
1.144 christos 896: int
1.169 fvdl 897: copyargs(struct proc *p, struct exec_package *pack, struct ps_strings *arginfo,
1.144 christos 898: char **stackp, void *argp)
1.67 christos 899: {
1.138 lukem 900: char **cpp, *dp, *sp;
901: size_t len;
902: void *nullp;
903: long argc, envc;
1.144 christos 904: int error;
1.138 lukem 905:
1.144 christos 906: cpp = (char **)*stackp;
1.138 lukem 907: nullp = NULL;
908: argc = arginfo->ps_nargvstr;
909: envc = arginfo->ps_nenvstr;
1.144 christos 910: if ((error = copyout(&argc, cpp++, sizeof(argc))) != 0)
911: return error;
1.67 christos 912:
1.124 jdolecek 913: dp = (char *) (cpp + argc + envc + 2 + pack->ep_es->es_arglen);
1.67 christos 914: sp = argp;
915:
916: /* XXX don't copy them out, remap them! */
1.69 mycroft 917: arginfo->ps_argvstr = cpp; /* remember location of argv for later */
1.67 christos 918:
919: for (; --argc >= 0; sp += len, dp += len)
1.144 christos 920: if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
921: (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
922: return error;
1.67 christos 923:
1.144 christos 924: if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
925: return error;
1.67 christos 926:
1.69 mycroft 927: arginfo->ps_envstr = cpp; /* remember location of envp for later */
1.67 christos 928:
929: for (; --envc >= 0; sp += len, dp += len)
1.144 christos 930: if ((error = copyout(&dp, cpp++, sizeof(dp))) != 0 ||
931: (error = copyoutstr(sp, dp, ARG_MAX, &len)) != 0)
932: return error;
1.67 christos 933:
1.144 christos 934: if ((error = copyout(&nullp, cpp++, sizeof(nullp))) != 0)
935: return error;
1.67 christos 936:
1.144 christos 937: *stackp = (char *)cpp;
938: return 0;
1.55 cgd 939: }
1.130 jdolecek 940:
941: #ifdef LKM
942: /*
943: * Find an emulation of given name in list of emulations.
1.151 jdolecek 944: * Needs to be called with the exec_lock held.
1.130 jdolecek 945: */
1.151 jdolecek 946: const struct emul *
1.138 lukem 947: emul_search(const char *name)
1.130 jdolecek 948: {
949: struct emul_entry *it;
950:
951: LIST_FOREACH(it, &el_head, el_list) {
952: if (strcmp(name, it->el_emul->e_name) == 0)
953: return it->el_emul;
954: }
955:
956: return NULL;
957: }
958:
959: /*
960: * Add an emulation to list, if it's not there already.
961: */
962: int
1.138 lukem 963: emul_register(const struct emul *emul, int ro_entry)
1.130 jdolecek 964: {
1.138 lukem 965: struct emul_entry *ee;
966: int error;
1.130 jdolecek 967:
1.138 lukem 968: error = 0;
1.130 jdolecek 969: lockmgr(&exec_lock, LK_SHARED, NULL);
970:
971: if (emul_search(emul->e_name)) {
972: error = EEXIST;
973: goto out;
974: }
975:
976: MALLOC(ee, struct emul_entry *, sizeof(struct emul_entry),
977: M_EXEC, M_WAITOK);
978: ee->el_emul = emul;
979: ee->ro_entry = ro_entry;
980: LIST_INSERT_HEAD(&el_head, ee, el_list);
981:
1.138 lukem 982: out:
1.130 jdolecek 983: lockmgr(&exec_lock, LK_RELEASE, NULL);
984: return error;
985: }
986:
987: /*
988: * Remove emulation with name 'name' from list of supported emulations.
989: */
990: int
1.138 lukem 991: emul_unregister(const char *name)
1.130 jdolecek 992: {
993: const struct proclist_desc *pd;
1.138 lukem 994: struct emul_entry *it;
995: int i, error;
996: struct proc *ptmp;
1.130 jdolecek 997:
1.138 lukem 998: error = 0;
1.130 jdolecek 999: lockmgr(&exec_lock, LK_SHARED, NULL);
1000:
1001: LIST_FOREACH(it, &el_head, el_list) {
1002: if (strcmp(it->el_emul->e_name, name) == 0)
1003: break;
1004: }
1005:
1006: if (!it) {
1007: error = ENOENT;
1008: goto out;
1009: }
1010:
1011: if (it->ro_entry) {
1012: error = EBUSY;
1013: goto out;
1014: }
1015:
1016: /* test if any execw[] entry is still using this */
1.132 jdolecek 1017: for(i=0; i < nexecs; i++) {
1.130 jdolecek 1018: if (execsw[i]->es_emul == it->el_emul) {
1019: error = EBUSY;
1020: goto out;
1021: }
1022: }
1023:
1024: /*
1025: * Test if any process is running under this emulation - since
1026: * emul_unregister() is running quite sendomly, it's better
1027: * to do expensive check here than to use any locking.
1028: */
1029: proclist_lock_read();
1030: for (pd = proclists; pd->pd_list != NULL && !error; pd++) {
1.191 yamt 1031: PROCLIST_FOREACH(ptmp, pd->pd_list) {
1.130 jdolecek 1032: if (ptmp->p_emul == it->el_emul) {
1033: error = EBUSY;
1034: break;
1035: }
1036: }
1037: }
1038: proclist_unlock_read();
1.183 junyoung 1039:
1.130 jdolecek 1040: if (error)
1041: goto out;
1042:
1.183 junyoung 1043:
1.130 jdolecek 1044: /* entry is not used, remove it */
1045: LIST_REMOVE(it, el_list);
1046: FREE(it, M_EXEC);
1047:
1.138 lukem 1048: out:
1.130 jdolecek 1049: lockmgr(&exec_lock, LK_RELEASE, NULL);
1050: return error;
1051: }
1052:
1053: /*
1054: * Add execsw[] entry.
1055: */
1056: int
1.138 lukem 1057: exec_add(struct execsw *esp, const char *e_name)
1.130 jdolecek 1058: {
1.138 lukem 1059: struct exec_entry *it;
1060: int error;
1.130 jdolecek 1061:
1.138 lukem 1062: error = 0;
1.130 jdolecek 1063: lockmgr(&exec_lock, LK_EXCLUSIVE, NULL);
1064:
1065: if (!esp->es_emul) {
1066: esp->es_emul = emul_search(e_name);
1067: if (!esp->es_emul) {
1068: error = ENOENT;
1069: goto out;
1070: }
1071: }
1072:
1073: LIST_FOREACH(it, &ex_head, ex_list) {
1074: /* assume tuple (makecmds, probe_func, emulation) is unique */
1.182 junyoung 1075: if (it->es->es_makecmds == esp->es_makecmds
1.130 jdolecek 1076: && it->es->u.elf_probe_func == esp->u.elf_probe_func
1077: && it->es->es_emul == esp->es_emul) {
1078: error = EEXIST;
1079: goto out;
1080: }
1081: }
1082:
1083: /* if we got here, the entry doesn't exist yet */
1084: MALLOC(it, struct exec_entry *, sizeof(struct exec_entry),
1085: M_EXEC, M_WAITOK);
1086: it->es = esp;
1087: LIST_INSERT_HEAD(&ex_head, it, ex_list);
1088:
1089: /* update execsw[] */
1090: exec_init(0);
1091:
1.138 lukem 1092: out:
1.130 jdolecek 1093: lockmgr(&exec_lock, LK_RELEASE, NULL);
1094: return error;
1095: }
1096:
1097: /*
1098: * Remove execsw[] entry.
1099: */
1100: int
1.138 lukem 1101: exec_remove(const struct execsw *esp)
1.130 jdolecek 1102: {
1.138 lukem 1103: struct exec_entry *it;
1104: int error;
1.130 jdolecek 1105:
1.138 lukem 1106: error = 0;
1.130 jdolecek 1107: lockmgr(&exec_lock, LK_EXCLUSIVE, NULL);
1108:
1109: LIST_FOREACH(it, &ex_head, ex_list) {
1110: /* assume tuple (makecmds, probe_func, emulation) is unique */
1.182 junyoung 1111: if (it->es->es_makecmds == esp->es_makecmds
1.130 jdolecek 1112: && it->es->u.elf_probe_func == esp->u.elf_probe_func
1113: && it->es->es_emul == esp->es_emul)
1114: break;
1115: }
1116: if (!it) {
1117: error = ENOENT;
1118: goto out;
1119: }
1120:
1121: /* remove item from list and free resources */
1122: LIST_REMOVE(it, ex_list);
1123: FREE(it, M_EXEC);
1124:
1125: /* update execsw[] */
1126: exec_init(0);
1127:
1.138 lukem 1128: out:
1.130 jdolecek 1129: lockmgr(&exec_lock, LK_RELEASE, NULL);
1130: return error;
1131: }
1132:
1133: static void
1.138 lukem 1134: link_es(struct execsw_entry **listp, const struct execsw *esp)
1.130 jdolecek 1135: {
1136: struct execsw_entry *et, *e1;
1137:
1138: MALLOC(et, struct execsw_entry *, sizeof(struct execsw_entry),
1139: M_TEMP, M_WAITOK);
1140: et->next = NULL;
1141: et->es = esp;
1142: if (*listp == NULL) {
1143: *listp = et;
1144: return;
1145: }
1146:
1147: switch(et->es->es_prio) {
1148: case EXECSW_PRIO_FIRST:
1149: /* put new entry as the first */
1150: et->next = *listp;
1151: *listp = et;
1152: break;
1153: case EXECSW_PRIO_ANY:
1154: /* put new entry after all *_FIRST and *_ANY entries */
1155: for(e1 = *listp; e1->next
1156: && e1->next->es->es_prio != EXECSW_PRIO_LAST;
1157: e1 = e1->next);
1158: et->next = e1->next;
1159: e1->next = et;
1160: break;
1161: case EXECSW_PRIO_LAST:
1162: /* put new entry as the last one */
1163: for(e1 = *listp; e1->next; e1 = e1->next);
1164: e1->next = et;
1165: break;
1166: default:
1167: #ifdef DIAGNOSTIC
1.157 provos 1168: panic("execw[] entry with unknown priority %d found",
1.130 jdolecek 1169: et->es->es_prio);
1170: #endif
1171: break;
1172: }
1173: }
1174:
1175: /*
1176: * Initialize exec structures. If init_boot is true, also does necessary
1177: * one-time initialization (it's called from main() that way).
1.147 jdolecek 1178: * Once system is multiuser, this should be called with exec_lock held,
1.130 jdolecek 1179: * i.e. via exec_{add|remove}().
1180: */
1181: int
1.138 lukem 1182: exec_init(int init_boot)
1.130 jdolecek 1183: {
1.138 lukem 1184: const struct execsw **new_es, * const *old_es;
1185: struct execsw_entry *list, *e1;
1186: struct exec_entry *e2;
1187: int i, es_sz;
1.130 jdolecek 1188:
1189: if (init_boot) {
1190: /* do one-time initializations */
1191: lockinit(&exec_lock, PWAIT, "execlck", 0, 0);
1192:
1193: /* register compiled-in emulations */
1194: for(i=0; i < nexecs_builtin; i++) {
1195: if (execsw_builtin[i].es_emul)
1196: emul_register(execsw_builtin[i].es_emul, 1);
1197: }
1198: #ifdef DIAGNOSTIC
1199: if (i == 0)
1.157 provos 1200: panic("no emulations found in execsw_builtin[]");
1.130 jdolecek 1201: #endif
1202: }
1203:
1204: /*
1205: * Build execsw[] array from builtin entries and entries added
1206: * at runtime.
1207: */
1208: list = NULL;
1209: for(i=0; i < nexecs_builtin; i++)
1210: link_es(&list, &execsw_builtin[i]);
1211:
1212: /* Add dynamically loaded entries */
1213: es_sz = nexecs_builtin;
1214: LIST_FOREACH(e2, &ex_head, ex_list) {
1215: link_es(&list, e2->es);
1216: es_sz++;
1217: }
1.183 junyoung 1218:
1.130 jdolecek 1219: /*
1220: * Now that we have sorted all execw entries, create new execsw[]
1221: * and free no longer needed memory in the process.
1222: */
1223: new_es = malloc(es_sz * sizeof(struct execsw *), M_EXEC, M_WAITOK);
1224: for(i=0; list; i++) {
1225: new_es[i] = list->es;
1226: e1 = list->next;
1227: FREE(list, M_TEMP);
1228: list = e1;
1229: }
1230:
1231: /*
1232: * New execsw[] array built, now replace old execsw[] and free
1233: * used memory.
1234: */
1235: old_es = execsw;
1236: execsw = new_es;
1237: nexecs = es_sz;
1238: if (old_es)
1239: free((void *)old_es, M_EXEC);
1240:
1241: /*
1242: * Figure out the maximum size of an exec header.
1.183 junyoung 1243: */
1.130 jdolecek 1244: exec_maxhdrsz = 0;
1245: for (i = 0; i < nexecs; i++) {
1246: if (execsw[i]->es_hdrsz > exec_maxhdrsz)
1247: exec_maxhdrsz = execsw[i]->es_hdrsz;
1248: }
1249:
1250: return 0;
1251: }
1252: #endif
1253:
1254: #ifndef LKM
1255: /*
1256: * Simplified exec_init() for kernels without LKMs. Only initialize
1257: * exec_maxhdrsz and execsw[].
1258: */
1259: int
1.138 lukem 1260: exec_init(int init_boot)
1.130 jdolecek 1261: {
1262: int i;
1263:
1264: #ifdef DIAGNOSTIC
1265: if (!init_boot)
1266: panic("exec_init(): called with init_boot == 0");
1267: #endif
1268:
1269: /* do one-time initializations */
1270: nexecs = nexecs_builtin;
1271: execsw = malloc(nexecs*sizeof(struct execsw *), M_EXEC, M_WAITOK);
1272:
1273: /*
1274: * Fill in execsw[] and figure out the maximum size of an exec header.
1275: */
1276: exec_maxhdrsz = 0;
1277: for(i=0; i < nexecs; i++) {
1278: execsw[i] = &execsw_builtin[i];
1279: if (execsw_builtin[i].es_hdrsz > exec_maxhdrsz)
1280: exec_maxhdrsz = execsw_builtin[i].es_hdrsz;
1281: }
1282:
1283: return 0;
1284:
1285: }
1286: #endif /* !LKM */
1.171 chs 1287:
1288: static int
1289: exec_sigcode_map(struct proc *p, const struct emul *e)
1290: {
1291: vaddr_t va;
1292: vsize_t sz;
1293: int error;
1294: struct uvm_object *uobj;
1295:
1.184 drochner 1296: sz = (vaddr_t)e->e_esigcode - (vaddr_t)e->e_sigcode;
1297:
1298: if (e->e_sigobject == NULL || sz == 0) {
1.171 chs 1299: return 0;
1300: }
1301:
1302: /*
1303: * If we don't have a sigobject for this emulation, create one.
1304: *
1305: * sigobject is an anonymous memory object (just like SYSV shared
1306: * memory) that we keep a permanent reference to and that we map
1307: * in all processes that need this sigcode. The creation is simple,
1308: * we create an object, add a permanent reference to it, map it in
1309: * kernel space, copy out the sigcode to it and unmap it.
1.189 jdolecek 1310: * We map it with PROT_READ|PROT_EXEC into the process just
1311: * the way sys_mmap() would map it.
1.171 chs 1312: */
1313:
1314: uobj = *e->e_sigobject;
1315: if (uobj == NULL) {
1316: uobj = uao_create(sz, 0);
1.181 christos 1317: (*uobj->pgops->pgo_reference)(uobj);
1.171 chs 1318: va = vm_map_min(kernel_map);
1319: if ((error = uvm_map(kernel_map, &va, round_page(sz),
1320: uobj, 0, 0,
1321: UVM_MAPFLAG(UVM_PROT_RW, UVM_PROT_RW,
1322: UVM_INH_SHARE, UVM_ADV_RANDOM, 0)))) {
1323: printf("kernel mapping failed %d\n", error);
1324: (*uobj->pgops->pgo_detach)(uobj);
1325: return (error);
1326: }
1327: memcpy((void *)va, e->e_sigcode, sz);
1328: #ifdef PMAP_NEED_PROCWR
1329: pmap_procwr(&proc0, va, sz);
1330: #endif
1331: uvm_unmap(kernel_map, va, va + round_page(sz));
1332: *e->e_sigobject = uobj;
1333: }
1334:
1.172 enami 1335: /* Just a hint to uvm_map where to put it. */
1.195 fvdl 1336: va = e->e_vm_default_addr(p, (vaddr_t)p->p_vmspace->vm_daddr,
1337: round_page(sz));
1.187 chs 1338:
1339: #ifdef __alpha__
1340: /*
1341: * Tru64 puts /sbin/loader at the end of user virtual memory,
1342: * which causes the above calculation to put the sigcode at
1343: * an invalid address. Put it just below the text instead.
1344: */
1.193 jmc 1345: if (va == (vaddr_t)vm_map_max(&p->p_vmspace->vm_map)) {
1.187 chs 1346: va = (vaddr_t)p->p_vmspace->vm_taddr - round_page(sz);
1347: }
1348: #endif
1349:
1.171 chs 1350: (*uobj->pgops->pgo_reference)(uobj);
1351: error = uvm_map(&p->p_vmspace->vm_map, &va, round_page(sz),
1352: uobj, 0, 0,
1353: UVM_MAPFLAG(UVM_PROT_RX, UVM_PROT_RX, UVM_INH_SHARE,
1354: UVM_ADV_RANDOM, 0));
1355: if (error) {
1356: (*uobj->pgops->pgo_detach)(uobj);
1357: return (error);
1358: }
1359: p->p_sigctx.ps_sigcode = (void *)va;
1360: return (0);
1361: }
CVSweb <webmaster@jp.NetBSD.org>