[BACK]Return to kern_exec.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

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>