[BACK]Return to osf1_exec.c CVS log [TXT][DIR] Up to [local] / sys / compat / osf1

Annotation of sys/compat/osf1/osf1_exec.c, Revision 1.1

1.1     ! nbrk        1: /* $OpenBSD: osf1_exec.c,v 1.5 2004/06/22 23:52:18 jfb Exp $ */
        !             2: /* $NetBSD$ */
        !             3:
        !             4: /*
        !             5:  * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
        !             6:  *
        !             7:  * Redistribution and use in source and binary forms, with or without
        !             8:  * modification, are permitted provided that the following conditions
        !             9:  * are met:
        !            10:  * 1. Redistributions of source code must retain the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer.
        !            12:  * 2. Redistributions in binary form must reproduce the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer in the
        !            14:  *    documentation and/or other materials provided with the distribution.
        !            15:  * 3. All advertising materials mentioning features or use of this software
        !            16:  *    must display the following acknowledgement:
        !            17:  *      This product includes software developed by Christopher G. Demetriou
        !            18:  *     for the NetBSD Project.
        !            19:  * 4. The name of the author may not be used to endorse or promote products
        !            20:  *    derived from this software without specific prior written permission
        !            21:  *
        !            22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #include <sys/param.h>
        !            35: #include <sys/systm.h>
        !            36: #include <sys/kernel.h>
        !            37: #include <sys/proc.h>
        !            38: #include <sys/malloc.h>
        !            39: #include <sys/namei.h>
        !            40: #include <sys/vnode.h>
        !            41: #include <sys/mount.h>
        !            42: #include <sys/exec.h>
        !            43: #include <sys/exec_ecoff.h>
        !            44: #include <sys/signalvar.h>
        !            45: #include <sys/fcntl.h>
        !            46: #include <sys/stat.h>
        !            47:
        !            48: #include <compat/osf1/osf1.h>
        !            49: #include <compat/osf1/osf1_syscall.h>
        !            50: #include <compat/osf1/osf1_util.h>
        !            51: #include <compat/osf1/osf1_cvt.h>
        !            52:
        !            53: extern int scdebug;
        !            54: extern char *osf1_syscallnames[];
        !            55:
        !            56:
        !            57: struct osf1_exec_emul_arg {
        !            58:         int        flags;
        !            59: #define OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER        0x01
        !            60:
        !            61:         char        exec_name[MAXPATHLEN+1];
        !            62:         char        loader_name[MAXPATHLEN+1];
        !            63: };
        !            64:
        !            65: static void *osf1_copyargs(struct exec_package *pack,
        !            66:        struct ps_strings *arginfo, void *stack, void *argp);
        !            67: int osf1_exec_ecoff_hook(struct proc *, struct exec_package *);
        !            68: static int osf1_exec_ecoff_dynamic(struct proc *, struct exec_package *);
        !            69:
        !            70: #define MAX_AUX_ENTRIES                4        /* max we'll ever push (right now) */
        !            71:
        !            72: extern struct sysent osf1_sysent[];
        !            73: extern void cpu_exec_ecoff_setregs(struct proc *, struct exec_package *,
        !            74:                                        u_long, register_t *);
        !            75: extern char osf1_sigcode[], osf1_esigcode[];
        !            76:
        !            77: struct emul emul_osf1 = {
        !            78:         "osf1",
        !            79:         NULL,
        !            80:         sendsig,
        !            81:         OSF1_SYS_syscall,
        !            82:         OSF1_SYS_MAXSYSCALL,
        !            83:         osf1_sysent,
        !            84: #ifdef SYSCALL_DEBUG
        !            85:         osf1_syscallnames,
        !            86: #else
        !            87:         NULL,
        !            88: #endif
        !            89:         0,
        !            90:         osf1_copyargs,
        !            91:         cpu_exec_ecoff_setregs,
        !            92:         NULL,
        !            93:         osf1_sigcode,
        !            94:         osf1_esigcode,
        !            95: };
        !            96:
        !            97: int
        !            98: osf1_exec_ecoff_hook(struct proc *p, struct exec_package *epp)
        !            99: {
        !           100:         struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr;
        !           101:        struct osf1_exec_emul_arg *emul_arg;
        !           102:        int error;
        !           103:
        !           104:        /* if we're here and we're exec-able at all, we're an OSF/1 binary */
        !           105:        epp->ep_emul = &emul_osf1;
        !           106:
        !           107:        /* set up the exec package emul arg as appropriate */
        !           108:        emul_arg = malloc(sizeof *emul_arg, M_TEMP, M_WAITOK);
        !           109:        epp->ep_emul_arg = emul_arg;
        !           110:
        !           111:        emul_arg->flags = 0;
        !           112:        if (epp->ep_ndp->ni_segflg == UIO_SYSSPACE)
        !           113:                error = copystr(epp->ep_ndp->ni_dirp, emul_arg->exec_name,
        !           114:                    MAXPATHLEN + 1, NULL);
        !           115:        else
        !           116:                error = copyinstr(epp->ep_ndp->ni_dirp, emul_arg->exec_name,
        !           117:                    MAXPATHLEN + 1, NULL);
        !           118: #ifdef DIAGNOSTIC
        !           119:        if (error != 0)
        !           120:                panic("osf1_exec_ecoff_hook: copyinstr failed");
        !           121: #endif
        !           122:
        !           123:        /* do any special object file handling */
        !           124:        switch (execp->f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {
        !           125:        case ECOFF_OBJECT_TYPE_SHARABLE:
        !           126:                /* can't exec a shared library! */
        !           127:                uprintf("can't execute OSF/1 shared libraries\n");
        !           128:                error = ENOEXEC;
        !           129:                break;
        !           130:
        !           131:        case ECOFF_OBJECT_TYPE_CALL_SHARED:
        !           132:                error = osf1_exec_ecoff_dynamic(p, epp);
        !           133:                break;
        !           134:
        !           135:        default:
        !           136:                /* just let the normal ECOFF handlers deal with it. */
        !           137:                error = 0;
        !           138:                break;
        !           139:        }
        !           140:
        !           141:        if (error) {
        !           142:                free(epp->ep_emul_arg, M_TEMP);
        !           143:                epp->ep_emul_arg = NULL;
        !           144:                kill_vmcmds(&epp->ep_vmcmds);           /* if any */
        !           145:        }
        !           146:
        !           147:        return (error);
        !           148: }
        !           149:
        !           150: /*
        !           151:  * copy arguments onto the stack in the normal way, then copy out
        !           152:  * any ELF-like AUX entries used by the dynamic loading scheme.
        !           153:  */
        !           154: static void *
        !           155: osf1_copyargs(pack, arginfo, stack, argp)
        !           156:        struct exec_package *pack;
        !           157:        struct ps_strings *arginfo;
        !           158:        void *stack;
        !           159:        void *argp;
        !           160: {
        !           161:        struct proc *p = curproc;                       /* XXX !!! */
        !           162:        struct osf1_exec_emul_arg *emul_arg = pack->ep_emul_arg;
        !           163:        struct osf1_auxv ai[MAX_AUX_ENTRIES], *a;
        !           164:        char *prognameloc, *loadernameloc;
        !           165:        size_t len;
        !           166:
        !           167:        stack = copyargs(pack, arginfo, stack, argp);
        !           168:        if (!stack)
        !           169:                goto bad;
        !           170:
        !           171:        a = ai;
        !           172:        memset(ai, 0, sizeof ai);
        !           173:
        !           174:        prognameloc = (char *)stack + sizeof ai;
        !           175:        if (copyoutstr(emul_arg->exec_name, prognameloc, MAXPATHLEN + 1, NULL))
        !           176:            goto bad;
        !           177:        a->a_type = OSF1_AT_EXEC_FILENAME;
        !           178:        a->a_un.a_ptr = prognameloc;
        !           179:        a++;
        !           180:
        !           181:        /*
        !           182:         * if there's a loader, push additional auxv entries on the stack.
        !           183:         */
        !           184:        if (emul_arg->flags & OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER) {
        !           185:
        !           186:                loadernameloc = prognameloc + MAXPATHLEN + 1;
        !           187:                if (copyoutstr(emul_arg->loader_name, loadernameloc,
        !           188:                    MAXPATHLEN + 1, NULL))
        !           189:                        goto bad;
        !           190:                a->a_type = OSF1_AT_EXEC_LOADER_FILENAME;
        !           191:                a->a_un.a_ptr = loadernameloc;
        !           192:                a++;
        !           193:
        !           194:                a->a_type = OSF1_AT_EXEC_LOADER_FLAGS;
        !           195:                a->a_un.a_val = 0;
        !           196:                 if (pack->ep_vap->va_mode & S_ISUID)
        !           197:                         a->a_un.a_val |= OSF1_LDR_EXEC_SETUID_F;
        !           198:                 if (pack->ep_vap->va_mode & S_ISGID)
        !           199:                         a->a_un.a_val |= OSF1_LDR_EXEC_SETGID_F;
        !           200:                if (p->p_flag & P_TRACED)
        !           201:                         a->a_un.a_val |= OSF1_LDR_EXEC_PTRACE_F;
        !           202:                a++;
        !           203:        }
        !           204:
        !           205:        a->a_type = OSF1_AT_NULL;
        !           206:        a->a_un.a_val = 0;
        !           207:        a++;
        !           208:
        !           209:        len = (a - ai) * sizeof(struct osf1_auxv);
        !           210:        if (copyout(ai, stack, len))
        !           211:                goto bad;
        !           212:        stack = (caddr_t)stack + len;
        !           213:
        !           214: out:
        !           215:        free(pack->ep_emul_arg, M_TEMP);
        !           216:        pack->ep_emul_arg = NULL;
        !           217:        return stack;
        !           218:
        !           219: bad:
        !           220:        stack = NULL;
        !           221:        goto out;
        !           222: }
        !           223:
        !           224: static int
        !           225: osf1_exec_ecoff_dynamic(struct proc *p, struct exec_package *epp)
        !           226: {
        !           227:        struct osf1_exec_emul_arg *emul_arg = epp->ep_emul_arg;
        !           228:        struct ecoff_exechdr ldr_exechdr;
        !           229:        struct nameidata nd;
        !           230:        struct vnode *ldr_vp;
        !           231:        char *pathbuf;
        !           232:         size_t resid;
        !           233:        int error;
        !           234:
        !           235:        /*
        !           236:         * locate the loader
        !           237:         */
        !           238:        error = emul_find(p, NULL, osf1_emul_path,
        !           239:            OSF1_LDR_EXEC_DEFAULT_LOADER, &pathbuf, 0);
        !           240:        /* includes /emul/osf1 if appropriate */
        !           241:        strlcpy(emul_arg->loader_name, pathbuf, sizeof(emul_arg->loader_name));
        !           242:        emul_arg->flags |= OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER;
        !           243:        if (!error)
        !           244:                free((char *)pathbuf, M_TEMP);
        !           245:
        !           246:        uprintf("loader is %s\n", emul_arg->loader_name);
        !           247:
        !           248:        /*
        !           249:         * open the loader, see if it's an ECOFF executable,
        !           250:         * make sure the object type is amenable, then arrange to
        !           251:         * load it up.
        !           252:         */
        !           253:        NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
        !           254:            emul_arg->loader_name, p);
        !           255:        if ((error = namei(&nd)) != 0)
        !           256:                goto bad_no_vp;
        !           257:        ldr_vp = nd.ni_vp;
        !           258:
        !           259:        /*
        !           260:         * Basic access checks.  Reject if:
        !           261:         *      not a regular file
        !           262:         *      exec not allowed on binary
        !           263:         *      exec not allowed on mount point
        !           264:         */
        !           265:        if (ldr_vp->v_type != VREG) {
        !           266:                error = EACCES;
        !           267:                goto badunlock;
        !           268:        }
        !           269:
        !           270:        if ((error = VOP_ACCESS(ldr_vp, VEXEC, p->p_ucred, p)) != 0)
        !           271:                goto badunlock;
        !           272:
        !           273:         if (ldr_vp->v_mount->mnt_flag & MNT_NOEXEC) {
        !           274:                 error = EACCES;
        !           275:                 goto badunlock;
        !           276:         }
        !           277:
        !           278:        /*
        !           279:         * If loader's mount point disallows set-id execution,
        !           280:         * disable set-id.
        !           281:         */
        !           282:         if (ldr_vp->v_mount->mnt_flag & MNT_NOSUID)
        !           283:                 epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
        !           284:
        !           285:        VOP_UNLOCK(ldr_vp, 0, p);
        !           286:
        !           287:        /*
        !           288:         * read the header, and make sure we got all of it.
        !           289:         */
        !           290:         if ((error = vn_rdwr(UIO_READ, ldr_vp, (caddr_t)&ldr_exechdr,
        !           291:            sizeof ldr_exechdr, 0, UIO_SYSSPACE, 0, p->p_ucred,
        !           292:            &resid, p)) != 0)
        !           293:                 goto bad;
        !           294:         if (resid != 0) {
        !           295:                 error = ENOEXEC;
        !           296:                 goto bad;
        !           297:        }
        !           298:
        !           299:        /*
        !           300:         * Check the magic.  We expect it to be the native Alpha ECOFF
        !           301:         * (Digital UNIX) magic number.  Also make sure it's not a shared
        !           302:         * lib or dynamically linked executable.
        !           303:         */
        !           304:        if (ldr_exechdr.f.f_magic != ECOFF_MAGIC_ALPHA) {
        !           305:                error = ENOEXEC;
        !           306:                goto bad;
        !           307:        }
        !           308:         switch (ldr_exechdr.f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {
        !           309:         case ECOFF_OBJECT_TYPE_SHARABLE:
        !           310:         case ECOFF_OBJECT_TYPE_CALL_SHARED:
        !           311:                /* can't exec shared lib or dynamically linked executable. */
        !           312:                error = ENOEXEC;
        !           313:                goto bad;
        !           314:        }
        !           315:
        !           316:        switch (ldr_exechdr.a.magic) {
        !           317:        case ECOFF_OMAGIC:
        !           318:                error = exec_ecoff_prep_omagic(p, epp);
        !           319:                break;
        !           320:        case ECOFF_NMAGIC:
        !           321:                error = exec_ecoff_prep_nmagic(p, epp);
        !           322:                break;
        !           323:        case ECOFF_ZMAGIC:
        !           324:                error = exec_ecoff_prep_zmagic(p, epp);
        !           325:                break;
        !           326:        default:
        !           327:                error = ENOEXEC;
        !           328:        }
        !           329:        if (error)
        !           330:                goto bad;
        !           331:
        !           332:        vrele(ldr_vp);
        !           333:        return (0);
        !           334:
        !           335: badunlock:
        !           336:        VOP_UNLOCK(ldr_vp, 0, p);
        !           337: bad:
        !           338:        vrele(ldr_vp);
        !           339: bad_no_vp:
        !           340:        return (error);
        !           341: }

CVSweb