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

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

CVSweb <webmaster@jp.NetBSD.org>