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