[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.191

1.191   ! yamt        1: /*     $NetBSD: kern_exec.c,v 1.190 2004/09/17 14:11:25 skrll 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.191   ! yamt       36: __KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.190 2004/09/17 14:11:25 skrll 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.55      cgd        41:
                     42: #include <sys/param.h>
                     43: #include <sys/systm.h>
                     44: #include <sys/filedesc.h>
                     45: #include <sys/kernel.h>
                     46: #include <sys/proc.h>
                     47: #include <sys/mount.h>
                     48: #include <sys/malloc.h>
                     49: #include <sys/namei.h>
                     50: #include <sys/vnode.h>
                     51: #include <sys/file.h>
                     52: #include <sys/acct.h>
                     53: #include <sys/exec.h>
                     54: #include <sys/ktrace.h>
                     55: #include <sys/resourcevar.h>
                     56: #include <sys/wait.h>
                     57: #include <sys/mman.h>
1.155     gmcgarry   58: #include <sys/ras.h>
1.55      cgd        59: #include <sys/signalvar.h>
                     60: #include <sys/stat.h>
1.124     jdolecek   61: #include <sys/syscall.h>
1.55      cgd        62:
1.164     thorpej    63: #include <sys/sa.h>
                     64: #include <sys/savar.h>
1.56      cgd        65: #include <sys/syscallargs.h>
1.55      cgd        66:
1.88      mrg        67: #include <uvm/uvm_extern.h>
                     68:
1.55      cgd        69: #include <machine/cpu.h>
                     70: #include <machine/reg.h>
                     71:
1.171     chs        72: static int exec_sigcode_map(struct proc *, const struct emul *);
                     73:
1.143     christos   74: #ifdef DEBUG_EXEC
                     75: #define DPRINTF(a) uprintf a
                     76: #else
                     77: #define DPRINTF(a)
                     78: #endif /* DEBUG_EXEC */
1.165     thorpej    79:
                     80: MALLOC_DEFINE(M_EXEC, "exec", "argument lists & other mem used by exec");
1.143     christos   81:
1.130     jdolecek   82: /*
                     83:  * Exec function switch:
                     84:  *
                     85:  * Note that each makecmds function is responsible for loading the
                     86:  * exec package with the necessary functions for any exec-type-specific
                     87:  * handling.
                     88:  *
                     89:  * Functions for specific exec types should be defined in their own
                     90:  * header file.
                     91:  */
1.138     lukem      92: extern const struct execsw     execsw_builtin[];
                     93: extern int                     nexecs_builtin;
                     94: static const struct execsw     **execsw = NULL;
                     95: static int                     nexecs;
                     96:
1.153     thorpej    97: u_int  exec_maxhdrsz;          /* must not be static - netbsd32 needs it */
1.130     jdolecek   98:
                     99: #ifdef LKM
                    100: /* list of supported emulations */
                    101: static
                    102: LIST_HEAD(emlist_head, emul_entry) el_head = LIST_HEAD_INITIALIZER(el_head);
                    103: struct emul_entry {
1.138     lukem     104:        LIST_ENTRY(emul_entry)  el_list;
                    105:        const struct emul       *el_emul;
                    106:        int                     ro_entry;
1.130     jdolecek  107: };
                    108:
                    109: /* list of dynamically loaded execsw entries */
                    110: static
                    111: LIST_HEAD(execlist_head, exec_entry) ex_head = LIST_HEAD_INITIALIZER(ex_head);
                    112: struct exec_entry {
1.138     lukem     113:        LIST_ENTRY(exec_entry)  ex_list;
                    114:        const struct execsw     *es;
1.130     jdolecek  115: };
                    116:
                    117: /* structure used for building execw[] */
                    118: struct execsw_entry {
1.138     lukem     119:        struct execsw_entry     *next;
                    120:        const struct execsw     *es;
1.130     jdolecek  121: };
                    122: #endif /* LKM */
                    123:
1.124     jdolecek  124: #ifdef SYSCALL_DEBUG
                    125: extern const char * const syscallnames[];
                    126: #endif
1.133     mycroft   127: #ifdef __HAVE_SYSCALL_INTERN
1.138     lukem     128: void syscall_intern(struct proc *);
1.133     mycroft   129: #else
1.138     lukem     130: void syscall(void);
1.133     mycroft   131: #endif
1.124     jdolecek  132:
1.185     drochner  133: #ifdef COMPAT_16
1.173     christos  134: extern char    sigcode[], esigcode[];
1.171     chs       135: struct uvm_object *emul_netbsd_object;
1.173     christos  136: #endif
1.171     chs       137:
1.173     christos  138: /* NetBSD emul struct */
1.124     jdolecek  139: const struct emul emul_netbsd = {
                    140:        "netbsd",
1.127     jdolecek  141:        NULL,           /* emulation path */
1.133     mycroft   142: #ifndef __HAVE_MINIMAL_EMUL
1.140     manu      143:        EMUL_HAS_SYS___syscall,
1.124     jdolecek  144:        NULL,
                    145:        SYS_syscall,
1.161     jdolecek  146:        SYS_NSYSENT,
1.133     mycroft   147: #endif
1.124     jdolecek  148:        sysent,
                    149: #ifdef SYSCALL_DEBUG
                    150:        syscallnames,
                    151: #else
                    152:        NULL,
                    153: #endif
1.133     mycroft   154:        sendsig,
1.142     christos  155:        trapsignal,
1.180     fvdl      156:        NULL,
1.185     drochner  157: #ifdef COMPAT_16
1.124     jdolecek  158:        sigcode,
                    159:        esigcode,
1.171     chs       160:        &emul_netbsd_object,
1.173     christos  161: #else
                    162:        NULL,
                    163:        NULL,
                    164:        NULL,
                    165: #endif
1.145     jdolecek  166:        setregs,
1.128     jdolecek  167:        NULL,
                    168:        NULL,
                    169:        NULL,
1.179     manu      170:        NULL,
                    171:        NULL,
1.133     mycroft   172: #ifdef __HAVE_SYSCALL_INTERN
                    173:        syscall_intern,
                    174: #else
                    175:        syscall,
                    176: #endif
1.156     manu      177:        NULL,
                    178:        NULL,
1.124     jdolecek  179: };
                    180:
1.147     jdolecek  181: #ifdef LKM
1.55      cgd       182: /*
1.130     jdolecek  183:  * Exec lock. Used to control access to execsw[] structures.
                    184:  * This must not be static so that netbsd32 can access it, too.
                    185:  */
                    186: struct lock exec_lock;
1.183     junyoung  187:
1.138     lukem     188: static void link_es(struct execsw_entry **, const struct execsw *);
1.130     jdolecek  189: #endif /* LKM */
                    190:
                    191: /*
1.55      cgd       192:  * check exec:
                    193:  * given an "executable" described in the exec package's namei info,
                    194:  * see what we can do with it.
                    195:  *
                    196:  * ON ENTRY:
                    197:  *     exec package with appropriate namei info
                    198:  *     proc pointer of exec'ing proc
1.160     blymn     199:  *      iff verified exec enabled then flag indicating a direct exec or
                    200:  *        an indirect exec (i.e. for a shell script interpreter)
1.55      cgd       201:  *     NO SELF-LOCKED VNODES
                    202:  *
                    203:  * ON EXIT:
                    204:  *     error:  nothing held, etc.  exec header still allocated.
1.77      cgd       205:  *     ok:     filled exec package, executable's vnode (unlocked).
1.55      cgd       206:  *
                    207:  * EXEC SWITCH ENTRY:
                    208:  *     Locked vnode to check, exec package, proc.
                    209:  *
                    210:  * EXEC SWITCH EXIT:
1.77      cgd       211:  *     ok:     return 0, filled exec package, executable's vnode (unlocked).
1.55      cgd       212:  *     error:  destructive:
                    213:  *                     everything deallocated execept exec header.
1.76      cgd       214:  *             non-destructive:
1.77      cgd       215:  *                     error code, executable's vnode (unlocked),
1.76      cgd       216:  *                     exec header unmodified.
1.55      cgd       217:  */
                    218: int
1.160     blymn     219: #ifdef VERIFIED_EXEC
1.169     fvdl      220: check_exec(struct proc *p, struct exec_package *epp, int direct_exec)
1.183     junyoung  221: #else
1.169     fvdl      222: check_exec(struct proc *p, struct exec_package *epp)
1.160     blymn     223: #endif
1.55      cgd       224: {
1.138     lukem     225:        int             error, i;
                    226:        struct vnode    *vp;
1.55      cgd       227:        struct nameidata *ndp;
1.138     lukem     228:        size_t          resid;
1.55      cgd       229:
                    230:        ndp = epp->ep_ndp;
                    231:        ndp->ni_cnd.cn_nameiop = LOOKUP;
                    232:        ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | SAVENAME;
                    233:        /* first get the vnode */
1.74      christos  234:        if ((error = namei(ndp)) != 0)
1.55      cgd       235:                return error;
                    236:        epp->ep_vp = vp = ndp->ni_vp;
                    237:
1.84      mycroft   238:        /* check access and type */
1.55      cgd       239:        if (vp->v_type != VREG) {
1.81      kleink    240:                error = EACCES;
1.55      cgd       241:                goto bad1;
                    242:        }
1.169     fvdl      243:        if ((error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p)) != 0)
1.84      mycroft   244:                goto bad1;
1.55      cgd       245:
                    246:        /* get attributes */
1.169     fvdl      247:        if ((error = VOP_GETATTR(vp, epp->ep_vap, p->p_ucred, p)) != 0)
1.55      cgd       248:                goto bad1;
                    249:
                    250:        /* Check mount point */
                    251:        if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
                    252:                error = EACCES;
                    253:                goto bad1;
                    254:        }
1.141     thorpej   255:        if (vp->v_mount->mnt_flag & MNT_NOSUID)
1.83      mycroft   256:                epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
1.55      cgd       257:
                    258:        /* try to open it */
1.169     fvdl      259:        if ((error = VOP_OPEN(vp, FREAD, p->p_ucred, p)) != 0)
1.55      cgd       260:                goto bad1;
                    261:
1.99      wrstuden  262:        /* unlock vp, since we need it unlocked from here on out. */
1.90      fvdl      263:        VOP_UNLOCK(vp, 0);
1.77      cgd       264:
1.183     junyoung  265:
1.160     blymn     266: #ifdef VERIFIED_EXEC
                    267:         /* Evaluate signature for file... */
                    268:         if ((error = check_veriexec(p, vp, epp, direct_exec)) != 0)
                    269:                 goto bad2;
                    270: #endif
                    271:
1.55      cgd       272:        /* now we have the file, get the exec header */
1.125     chs       273:        uvn_attach(vp, VM_PROT_READ);
1.74      christos  274:        error = vn_rdwr(UIO_READ, vp, epp->ep_hdr, epp->ep_hdrlen, 0,
1.190     skrll     275:                        UIO_SYSSPACE, 0, p->p_ucred, &resid, NULL);
1.74      christos  276:        if (error)
1.55      cgd       277:                goto bad2;
                    278:        epp->ep_hdrvalid = epp->ep_hdrlen - resid;
                    279:
                    280:        /*
1.136     eeh       281:         * Set up default address space limits.  Can be overridden
                    282:         * by individual exec packages.
1.183     junyoung  283:         *
1.167     manu      284:         * XXX probably should be all done in the exec pakages.
1.136     eeh       285:         */
                    286:        epp->ep_vm_minaddr = VM_MIN_ADDRESS;
                    287:        epp->ep_vm_maxaddr = VM_MAXUSER_ADDRESS;
                    288:        /*
1.55      cgd       289:         * set up the vmcmds for creation of the process
                    290:         * address space
                    291:         */
                    292:        error = ENOEXEC;
                    293:        for (i = 0; i < nexecs && error != 0; i++) {
1.68      cgd       294:                int newerror;
                    295:
1.130     jdolecek  296:                epp->ep_esch = execsw[i];
1.182     junyoung  297:                newerror = (*execsw[i]->es_makecmds)(p, epp);
1.68      cgd       298:                /* make sure the first "interesting" error code is saved. */
                    299:                if (!newerror || error == ENOEXEC)
                    300:                        error = newerror;
1.124     jdolecek  301:
1.182     junyoung  302:                /* if es_makecmds call was successful, update epp->ep_es */
1.124     jdolecek  303:                if (!newerror && (epp->ep_flags & EXEC_HASES) == 0)
1.130     jdolecek  304:                        epp->ep_es = execsw[i];
1.124     jdolecek  305:
1.55      cgd       306:                if (epp->ep_flags & EXEC_DESTR && error != 0)
                    307:                        return error;
                    308:        }
                    309:        if (!error) {
                    310:                /* check that entry point is sane */
                    311:                if (epp->ep_entry > VM_MAXUSER_ADDRESS)
                    312:                        error = ENOEXEC;
                    313:
                    314:                /* check limits */
                    315:                if ((epp->ep_tsize > MAXTSIZ) ||
1.153     thorpej   316:                    (epp->ep_dsize >
                    317:                     (u_quad_t)p->p_rlimit[RLIMIT_DATA].rlim_cur))
1.55      cgd       318:                        error = ENOMEM;
                    319:
                    320:                if (!error)
                    321:                        return (0);
                    322:        }
                    323:
                    324:        /*
                    325:         * free any vmspace-creation commands,
                    326:         * and release their references
                    327:         */
                    328:        kill_vmcmds(&epp->ep_vmcmds);
                    329:
                    330: bad2:
                    331:        /*
1.99      wrstuden  332:         * close and release the vnode, restore the old one, free the
1.55      cgd       333:         * pathname buf, and punt.
                    334:         */
1.99      wrstuden  335:        vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
1.169     fvdl      336:        VOP_CLOSE(vp, FREAD, p->p_ucred, p);
1.99      wrstuden  337:        vput(vp);
1.120     thorpej   338:        PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
1.55      cgd       339:        return error;
                    340:
                    341: bad1:
                    342:        /*
                    343:         * free the namei pathname buffer, and put the vnode
                    344:         * (which we don't yet have open).
                    345:         */
1.77      cgd       346:        vput(vp);                               /* was still locked */
1.120     thorpej   347:        PNBUF_PUT(ndp->ni_cnd.cn_pnbuf);
1.55      cgd       348:        return error;
                    349: }
                    350:
1.188     chs       351: #ifdef __MACHINE_STACK_GROWS_UP
                    352: #define STACK_PTHREADSPACE NBPG
                    353: #else
                    354: #define STACK_PTHREADSPACE 0
                    355: #endif
                    356:
1.55      cgd       357: /*
                    358:  * exec system call
                    359:  */
                    360: /* ARGSUSED */
1.75      christos  361: int
1.164     thorpej   362: sys_execve(struct lwp *l, void *v, register_t *retval)
1.71      thorpej   363: {
1.108     augustss  364:        struct sys_execve_args /* {
1.138     lukem     365:                syscallarg(const char *)        path;
                    366:                syscallarg(char * const *)      argp;
                    367:                syscallarg(char * const *)      envp;
1.71      thorpej   368:        } */ *uap = v;
1.153     thorpej   369:        int                     error;
                    370:        u_int                   i;
1.138     lukem     371:        struct exec_package     pack;
                    372:        struct nameidata        nid;
                    373:        struct vattr            attr;
1.164     thorpej   374:        struct proc             *p;
1.138     lukem     375:        struct ucred            *cred;
                    376:        char                    *argp;
                    377:        char * const            *cpp;
                    378:        char                    *dp, *sp;
                    379:        long                    argc, envc;
                    380:        size_t                  len;
                    381:        char                    *stack;
                    382:        struct ps_strings       arginfo;
                    383:        struct vmspace          *vm;
                    384:        char                    **tmpfap;
                    385:        int                     szsigcode;
                    386:        struct exec_vmcmd       *base_vcp;
1.164     thorpej   387:        int                     oldlwpflags;
1.55      cgd       388:
1.164     thorpej   389:        /* Disable scheduler activation upcalls. */
                    390:        oldlwpflags = l->l_flag & (L_SA | L_SA_UPCALL);
                    391:        if (l->l_flag & L_SA)
                    392:                l->l_flag &= ~(L_SA | L_SA_UPCALL);
                    393:
                    394:        p = l->l_proc;
1.149     christos  395:        /*
                    396:         * Lock the process and set the P_INEXEC flag to indicate that
                    397:         * it should be left alone until we're done here.  This is
                    398:         * necessary to avoid race conditions - e.g. in ptrace() -
                    399:         * that might allow a local user to illicitly obtain elevated
                    400:         * privileges.
                    401:         */
                    402:        p->p_flag |= P_INEXEC;
                    403:
1.138     lukem     404:        cred = p->p_ucred;
                    405:        base_vcp = NULL;
1.55      cgd       406:        /*
1.129     jdolecek  407:         * Init the namei data to point the file user's program name.
                    408:         * This is done here rather than in check_exec(), so that it's
                    409:         * possible to override this settings if any of makecmd/probe
                    410:         * functions call check_exec() recursively - for example,
                    411:         * see exec_script_makecmds().
                    412:         */
1.169     fvdl      413:        NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
1.55      cgd       414:
                    415:        /*
                    416:         * initialize the fields of the exec package.
                    417:         */
1.56      cgd       418:        pack.ep_name = SCARG(uap, path);
1.119     thorpej   419:        pack.ep_hdr = malloc(exec_maxhdrsz, M_EXEC, M_WAITOK);
1.55      cgd       420:        pack.ep_hdrlen = exec_maxhdrsz;
                    421:        pack.ep_hdrvalid = 0;
                    422:        pack.ep_ndp = &nid;
1.67      christos  423:        pack.ep_emul_arg = NULL;
1.55      cgd       424:        pack.ep_vmcmds.evs_cnt = 0;
                    425:        pack.ep_vmcmds.evs_used = 0;
                    426:        pack.ep_vap = &attr;
                    427:        pack.ep_flags = 0;
                    428:
1.147     jdolecek  429: #ifdef LKM
1.130     jdolecek  430:        lockmgr(&exec_lock, LK_SHARED, NULL);
1.147     jdolecek  431: #endif
1.130     jdolecek  432:
1.55      cgd       433:        /* see if we can run it. */
1.160     blymn     434: #ifdef VERIFIED_EXEC
1.169     fvdl      435:         if ((error = check_exec(p, &pack, 1)) != 0)
                    436:         /* if ((error = check_exec(p, &pack, 0)) != 0) */
1.183     junyoung  437: #else
1.169     fvdl      438:         if ((error = check_exec(p, &pack)) != 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:        /*
                    787:         * Call emulation specific exec hook. This can setup setup per-process
                    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.119     thorpej   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:         */
                   1341:        if (va == (vaddr_t)p->p_vmspace->vm_map.max_offset) {
                   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>