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

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

CVSweb <webmaster@jp.NetBSD.org>