Annotation of 43BSDReno/sys/kern/kern_exec.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution is only permitted until one year after the first shipment
        !             6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !             7:  * binary forms are permitted provided that: (1) source distributions retain
        !             8:  * this entire copyright notice and comment, and (2) distributions including
        !             9:  * binaries display the following acknowledgement:  This product includes
        !            10:  * software developed by the University of California, Berkeley and its
        !            11:  * contributors'' in the documentation or other materials provided with the
        !            12:  * distribution and in all advertising materials mentioning features or use
        !            13:  * of this software.  Neither the name of the University nor the names of
        !            14:  * its contributors may be used to endorse or promote products derived from
        !            15:  * this software without specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  *
        !            20:  *     @(#)kern_exec.c 7.30 (Berkeley) 6/30/90
        !            21:  */
        !            22: 
        !            23: #include "param.h"
        !            24: #include "systm.h"
        !            25: #include "map.h"
        !            26: #include "user.h"
        !            27: #include "kernel.h"
        !            28: #include "proc.h"
        !            29: #include "mount.h"
        !            30: #include "ucred.h"
        !            31: #include "malloc.h"
        !            32: #include "buf.h"
        !            33: #include "vnode.h"
        !            34: #include "seg.h"
        !            35: #include "vm.h"
        !            36: #include "text.h"
        !            37: #include "file.h"
        !            38: #include "uio.h"
        !            39: #include "acct.h"
        !            40: #include "exec.h"
        !            41: 
        !            42: #include "machine/reg.h"
        !            43: #include "machine/pte.h"
        !            44: #include "machine/psl.h"
        !            45: #include "machine/mtpr.h"
        !            46: 
        !            47: #ifdef HPUXCOMPAT
        !            48: #include "../hpux/hpux_exec.h"
        !            49: #endif
        !            50: 
        !            51: /*
        !            52:  * exec system call, with and without environments.
        !            53:  */
        !            54: execv(p, uap, retval)
        !            55:        struct proc *p;
        !            56:        struct args {
        !            57:                char    *fname;
        !            58:                char    **argp;
        !            59:                char    **envp;
        !            60:        } *uap;
        !            61:        int *retval;
        !            62: {
        !            63: 
        !            64:        uap->envp = NULL;
        !            65:        return (execve(p, uap, retval));
        !            66: }
        !            67: 
        !            68: /* ARGSUSED */
        !            69: execve(p, uap, retval)
        !            70:        register struct proc *p;
        !            71:        register struct args {
        !            72:                char    *fname;
        !            73:                char    **argp;
        !            74:                char    **envp;
        !            75:        } *uap;
        !            76:        int *retval;
        !            77: {
        !            78:        register nc;
        !            79:        register char *cp;
        !            80:        register struct buf *bp;
        !            81:        struct buf *tbp;
        !            82:        int na, ne, ucp, ap, cc;
        !            83:        unsigned len;
        !            84:        int indir, uid, gid;
        !            85:        char *sharg;
        !            86:        struct vnode *vp;
        !            87:        swblk_t bno;
        !            88:        struct vattr vattr;
        !            89:        char cfname[MAXCOMLEN + 1];
        !            90:        char cfarg[MAXINTERP];
        !            91:        union {
        !            92:                char    ex_shell[MAXINTERP];    /* #! and interpreter name */
        !            93:                struct  exec ex_exec;
        !            94: #ifdef HPUXCOMPAT
        !            95:                struct  hpux_exec ex_hexec;
        !            96: #endif
        !            97:        } exdata;
        !            98: #ifdef HPUXCOMPAT
        !            99:        struct hpux_exec hhead;
        !           100: #endif
        !           101:        register struct ucred *cred = u.u_cred;
        !           102:        register struct nameidata *ndp = &u.u_nd;
        !           103:        int resid, error, flags = 0;
        !           104: 
        !           105:   start:
        !           106:        ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        !           107:        ndp->ni_segflg = UIO_USERSPACE;
        !           108:        ndp->ni_dirp = uap->fname;
        !           109:        if (error = namei(ndp))
        !           110:                return (error);
        !           111:        vp = ndp->ni_vp;
        !           112:        bno = 0;
        !           113:        bp = 0;
        !           114:        indir = 0;
        !           115:        uid = cred->cr_uid;
        !           116:        gid = cred->cr_gid;
        !           117:        if (error = VOP_GETATTR(vp, &vattr, cred))
        !           118:                goto bad;
        !           119:        if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
        !           120:                error = EACCES;
        !           121:                goto bad;
        !           122:        }
        !           123:        if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) {
        !           124:                if (vattr.va_mode & VSUID)
        !           125:                        uid = vattr.va_uid;
        !           126:                if (vattr.va_mode & VSGID)
        !           127:                        gid = vattr.va_gid;
        !           128:        }
        !           129: 
        !           130:   again:
        !           131:        if (error = VOP_ACCESS(vp, VEXEC, cred))
        !           132:                goto bad;
        !           133:        if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred)))
        !           134:                goto bad;
        !           135:        if (vp->v_type != VREG ||
        !           136:            (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
        !           137:                error = EACCES;
        !           138:                goto bad;
        !           139:        }
        !           140: 
        !           141:        /*
        !           142:         * Read in first few bytes of file for segment sizes, magic number:
        !           143:         *      OMAGIC = plain executable
        !           144:         *      NMAGIC = RO text
        !           145:         *      ZMAGIC = demand paged RO text
        !           146:         * Also an ASCII line beginning with #! is
        !           147:         * the file name of a ``shell'' and arguments may be prepended
        !           148:         * to the argument list if given here.
        !           149:         *
        !           150:         * SHELL NAMES ARE LIMITED IN LENGTH.
        !           151:         *
        !           152:         * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
        !           153:         * THE ASCII LINE.
        !           154:         */
        !           155:        exdata.ex_shell[0] = '\0';      /* for zero length files */
        !           156:        error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
        !           157:            (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid);
        !           158:        if (error)
        !           159:                goto bad;
        !           160: #ifndef lint
        !           161:        if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
        !           162:            exdata.ex_shell[0] != '#') {
        !           163:                error = ENOEXEC;
        !           164:                goto bad;
        !           165:        }
        !           166: #endif
        !           167: #if defined(hp300)
        !           168:        switch ((int)exdata.ex_exec.a_mid) {
        !           169: 
        !           170:        /*
        !           171:         * An ancient hp200 or hp300 binary, shouldn't happen anymore.
        !           172:         * Mark as invalid.
        !           173:         */
        !           174:        case MID_ZERO:
        !           175:                exdata.ex_exec.a_magic = 0;
        !           176:                break;
        !           177: 
        !           178:        /*
        !           179:         * HP200 series has a smaller page size so we cannot
        !           180:         * demand-load or even write protect text, so we just
        !           181:         * treat as OMAGIC.
        !           182:         */
        !           183:        case MID_HP200:
        !           184:                exdata.ex_exec.a_magic = OMAGIC;
        !           185:                break;
        !           186: 
        !           187:        case MID_HP300:
        !           188:                break;
        !           189: 
        !           190: #ifdef HPUXCOMPAT
        !           191:        case MID_HPUX:
        !           192:                /*
        !           193:                 * Save a.out header.  This is eventually saved in the pcb,
        !           194:                 * but we cannot do that yet in case the exec fails before
        !           195:                 * the image is overlayed.
        !           196:                 */
        !           197:                bcopy((caddr_t)&exdata.ex_hexec,
        !           198:                      (caddr_t)&hhead, sizeof hhead);
        !           199:                /*
        !           200:                 * If version number is 0x2bad this is a native BSD
        !           201:                 * binary created via the HPUX SGS.  Should not be
        !           202:                 * treated as an HPUX binary.
        !           203:                 */
        !           204:                if (exdata.ex_hexec.ha_version != BSDVNUM)
        !           205:                        flags |= SHPUX;
        !           206:                /*
        !           207:                 * Shuffle important fields to their BSD locations.
        !           208:                 * Note that the order in which this is done is important.
        !           209:                 */
        !           210:                exdata.ex_exec.a_text = exdata.ex_hexec.ha_text;
        !           211:                exdata.ex_exec.a_data = exdata.ex_hexec.ha_data;
        !           212:                exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss;
        !           213:                exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry;
        !           214:                /*
        !           215:                 * For ZMAGIC files, make sizes consistant with those
        !           216:                 * generated by BSD ld.
        !           217:                 */
        !           218:                if (exdata.ex_exec.a_magic == ZMAGIC) {
        !           219:                        exdata.ex_exec.a_text = 
        !           220:                                ctob(btoc(exdata.ex_exec.a_text));
        !           221:                        nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss;
        !           222:                        exdata.ex_exec.a_data =
        !           223:                                ctob(btoc(exdata.ex_exec.a_data));
        !           224:                        nc -= (int)exdata.ex_exec.a_data;
        !           225:                        exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc;
        !           226:                }
        !           227:                break;
        !           228: #endif
        !           229:        }
        !           230: #endif
        !           231:        switch ((int)exdata.ex_exec.a_magic) {
        !           232: 
        !           233:        case OMAGIC:
        !           234:                exdata.ex_exec.a_data += exdata.ex_exec.a_text;
        !           235:                exdata.ex_exec.a_text = 0;
        !           236:                break;
        !           237: 
        !           238:        case ZMAGIC:
        !           239:                flags |= SPAGV;
        !           240:        case NMAGIC:
        !           241:                if (exdata.ex_exec.a_text == 0) {
        !           242:                        error = ENOEXEC;
        !           243:                        goto bad;
        !           244:                }
        !           245:                break;
        !           246: 
        !           247:        default:
        !           248:                if (exdata.ex_shell[0] != '#' ||
        !           249:                    exdata.ex_shell[1] != '!' ||
        !           250:                    indir) {
        !           251:                        error = ENOEXEC;
        !           252:                        goto bad;
        !           253:                }
        !           254:                for (cp = &exdata.ex_shell[2];; ++cp) {
        !           255:                        if (cp >= &exdata.ex_shell[MAXINTERP]) {
        !           256:                                error = ENOEXEC;
        !           257:                                goto bad;
        !           258:                        }
        !           259:                        if (*cp == '\n') {
        !           260:                                *cp = '\0';
        !           261:                                break;
        !           262:                        }
        !           263:                        if (*cp == '\t')
        !           264:                                *cp = ' ';
        !           265:                }
        !           266:                cp = &exdata.ex_shell[2];
        !           267:                while (*cp == ' ')
        !           268:                        cp++;
        !           269:                ndp->ni_dirp = cp;
        !           270:                while (*cp && *cp != ' ')
        !           271:                        cp++;
        !           272:                cfarg[0] = '\0';
        !           273:                if (*cp) {
        !           274:                        *cp++ = '\0';
        !           275:                        while (*cp == ' ')
        !           276:                                cp++;
        !           277:                        if (*cp)
        !           278:                                bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
        !           279:                }
        !           280:                indir = 1;
        !           281:                vput(vp);
        !           282:                ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
        !           283:                ndp->ni_segflg = UIO_SYSSPACE;
        !           284:                if (error = namei(ndp))
        !           285:                        return (error);
        !           286:                vp = ndp->ni_vp;
        !           287:                if (error = VOP_GETATTR(vp, &vattr, cred))
        !           288:                        goto bad;
        !           289:                bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
        !           290:                    MAXCOMLEN);
        !           291:                cfname[MAXCOMLEN] = '\0';
        !           292:                uid = cred->cr_uid;     /* shell scripts can't be setuid */
        !           293:                gid = cred->cr_gid;
        !           294:                goto again;
        !           295:        }
        !           296:        /*
        !           297:         * If the vnode has been modified since we last used it,
        !           298:         * then throw away all its pages and its text table entry.
        !           299:         */
        !           300:        if (vp->v_text && vp->v_text->x_mtime != vattr.va_mtime.tv_sec) {
        !           301:                /*
        !           302:                 * Try once to release, if it is still busy
        !           303:                 * take more drastic action.
        !           304:                 */
        !           305:                xrele(vp);
        !           306:                if (vp->v_flag & VTEXT) {
        !           307:                        vput(vp);
        !           308:                        vgone(vp);
        !           309:                        goto start;
        !           310:                }
        !           311:        }
        !           312: 
        !           313:        /*
        !           314:         * Collect arguments on "file" in swap space.
        !           315:         */
        !           316:        na = 0;
        !           317:        ne = 0;
        !           318:        nc = 0;
        !           319:        cc = 0;
        !           320:        bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))));
        !           321:        if (bno == 0) {
        !           322:                swkill(p, "exec: no swap space");
        !           323:                goto bad;
        !           324:        }
        !           325:        if (bno % CLSIZE)
        !           326:                panic("execa rmalloc");
        !           327: #ifdef GENERIC
        !           328:        if (rootdev == dumpdev)
        !           329:                bno += 4096;
        !           330: #endif
        !           331:        /*
        !           332:         * Copy arguments into file in argdev area.
        !           333:         */
        !           334:        if (uap->argp) for (;;) {
        !           335:                ap = NULL;
        !           336:                sharg = NULL;
        !           337:                if (indir && na == 0) {
        !           338:                        sharg = cfname;
        !           339:                        ap = (int)sharg;
        !           340:                        uap->argp++;            /* ignore argv[0] */
        !           341:                } else if (indir && (na == 1 && cfarg[0])) {
        !           342:                        sharg = cfarg;
        !           343:                        ap = (int)sharg;
        !           344:                } else if (indir && (na == 1 || na == 2 && cfarg[0]))
        !           345:                        ap = (int)uap->fname;
        !           346:                else if (uap->argp) {
        !           347:                        ap = fuword((caddr_t)uap->argp);
        !           348:                        uap->argp++;
        !           349:                }
        !           350:                if (ap == NULL && uap->envp) {
        !           351:                        uap->argp = NULL;
        !           352:                        if ((ap = fuword((caddr_t)uap->envp)) != NULL)
        !           353:                                uap->envp++, ne++;
        !           354:                }
        !           355:                if (ap == NULL)
        !           356:                        break;
        !           357:                na++;
        !           358:                if (ap == -1) {
        !           359:                        error = EFAULT;
        !           360:                        if (bp) {
        !           361:                                brelse(bp);
        !           362:                                bp = 0;
        !           363:                        }
        !           364:                        goto badarg;
        !           365:                }
        !           366:                do {
        !           367:                        if (cc <= 0) {
        !           368:                                /*
        !           369:                                 * We depend on NCARGS being a multiple of
        !           370:                                 * CLBYTES.  This way we need only check
        !           371:                                 * overflow before each buffer allocation.
        !           372:                                 */
        !           373:                                if (nc >= NCARGS-1) {
        !           374:                                        error = E2BIG;
        !           375:                                        break;
        !           376:                                }
        !           377:                                if (bp)
        !           378:                                        bdwrite(bp);
        !           379:                                cc = CLBYTES;
        !           380:                                bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc);
        !           381:                                cp = bp->b_un.b_addr;
        !           382:                        }
        !           383:                        if (sharg) {
        !           384:                                error = copystr(sharg, cp, (unsigned)cc, &len);
        !           385:                                sharg += len;
        !           386:                        } else {
        !           387:                                error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
        !           388:                                    &len);
        !           389:                                ap += len;
        !           390:                        }
        !           391:                        cp += len;
        !           392:                        nc += len;
        !           393:                        cc -= len;
        !           394:                } while (error == ENOENT);
        !           395:                if (error) {
        !           396:                        if (bp)
        !           397:                                brelse(bp);
        !           398:                        bp = 0;
        !           399:                        goto badarg;
        !           400:                }
        !           401:        }
        !           402:        if (bp)
        !           403:                bdwrite(bp);
        !           404:        bp = 0;
        !           405:        nc = (nc + NBPW-1) & ~(NBPW-1);
        !           406:        error = getxfile(p, vp, &exdata.ex_exec, flags, nc + (na+4)*NBPW,
        !           407:            uid, gid);
        !           408:        if (error) {
        !           409: badarg:
        !           410:                for (cc = 0; cc < nc; cc += CLBYTES) {
        !           411:                        (void) baddr(argdev_vp, bno + ctod(cc/NBPG),
        !           412:                                CLBYTES, NOCRED, &tbp);
        !           413:                        bp = tbp;
        !           414:                        if (bp) {
        !           415:                                bp->b_flags |= B_INVAL;         /* throw away */
        !           416:                                brelse(bp);
        !           417:                                bp = 0;
        !           418:                        }
        !           419:                }
        !           420:                goto bad;
        !           421:        }
        !           422:        if (vp->v_text)
        !           423:                vp->v_text->x_mtime = vattr.va_mtime.tv_sec;
        !           424:        vput(vp);
        !           425:        vp = NULL;
        !           426: 
        !           427: #ifdef HPUXCOMPAT
        !           428:        /*
        !           429:         * We are now committed to the exec so we can save the exec
        !           430:         * header in the pcb where we can dump it if necessary in core()
        !           431:         */
        !           432:        if (u.u_pcb.pcb_flags & PCB_HPUXBIN)
        !           433:                bcopy((caddr_t)&hhead,
        !           434:                      (caddr_t)u.u_pcb.pcb_exec, sizeof hhead);
        !           435: #endif
        !           436: 
        !           437:        /*
        !           438:         * Copy back arglist.
        !           439:         */
        !           440:        ucp = USRSTACK - nc - NBPW;
        !           441:        ap = ucp - na*NBPW - 3*NBPW;
        !           442:        u.u_ar0[SP] = ap;
        !           443:        (void) suword((caddr_t)ap, na-ne);
        !           444:        nc = 0;
        !           445:        cc = 0;
        !           446:        for (;;) {
        !           447:                ap += NBPW;
        !           448:                if (na == ne) {
        !           449:                        (void) suword((caddr_t)ap, 0);
        !           450:                        ap += NBPW;
        !           451:                }
        !           452:                if (--na < 0)
        !           453:                        break;
        !           454:                (void) suword((caddr_t)ap, ucp);
        !           455:                do {
        !           456:                        if (cc <= 0) {
        !           457:                                if (bp)
        !           458:                                        brelse(bp);
        !           459:                                cc = CLBYTES;
        !           460:                                error = bread(argdev_vp,
        !           461:                                    (daddr_t)(bno + ctod(nc / NBPG)), cc,
        !           462:                                    NOCRED, &tbp);
        !           463:                                bp = tbp;
        !           464:                                bp->b_flags |= B_INVAL;         /* throw away */
        !           465:                                cp = bp->b_un.b_addr;
        !           466:                        }
        !           467:                        error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
        !           468:                            &len);
        !           469:                        ucp += len;
        !           470:                        cp += len;
        !           471:                        nc += len;
        !           472:                        cc -= len;
        !           473:                } while (error == ENOENT);
        !           474:                if (error == EFAULT)
        !           475:                        panic("exec: EFAULT");
        !           476:        }
        !           477:        (void) suword((caddr_t)ap, 0);
        !           478: 
        !           479:        execsigs(p);
        !           480: 
        !           481:        for (nc = u.u_lastfile; nc >= 0; --nc) {
        !           482:                if (u.u_pofile[nc] & UF_EXCLOSE) {
        !           483:                        (void) closef(u.u_ofile[nc]);
        !           484:                        u.u_ofile[nc] = NULL;
        !           485:                        u.u_pofile[nc] = 0;
        !           486:                }
        !           487:                u.u_pofile[nc] &= ~UF_MAPPED;
        !           488:        }
        !           489:        while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL)
        !           490:                u.u_lastfile--;
        !           491:        setregs(exdata.ex_exec.a_entry, retval);
        !           492:        /*
        !           493:         * Remember file name for accounting.
        !           494:         */
        !           495:        u.u_acflag &= ~AFORK;
        !           496:        if (indir)
        !           497:                bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN);
        !           498:        else {
        !           499:                if (ndp->ni_dent.d_namlen > MAXCOMLEN)
        !           500:                        ndp->ni_dent.d_namlen = MAXCOMLEN;
        !           501:                bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm,
        !           502:                    (unsigned)(ndp->ni_dent.d_namlen + 1));
        !           503:        }
        !           504: bad:
        !           505:        if (bp)
        !           506:                brelse(bp);
        !           507:        if (bno)
        !           508:                rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno);
        !           509:        if (vp)
        !           510:                vput(vp);
        !           511:        return (error);
        !           512: }
        !           513: 
        !           514: /*
        !           515:  * Read in and set up memory for executed file.
        !           516:  */
        !           517: getxfile(p, vp, ep, flags, nargc, uid, gid)
        !           518:        register struct proc *p;
        !           519:        register struct vnode *vp;
        !           520:        register struct exec *ep;
        !           521:        int flags, nargc, uid, gid;
        !           522: {
        !           523:        segsz_t ts, ds, ids, uds, ss;
        !           524:        register struct ucred *cred = u.u_cred;
        !           525:        off_t toff;
        !           526:        int error;
        !           527: 
        !           528: #ifdef HPUXCOMPAT
        !           529:        if (ep->a_mid == MID_HPUX)
        !           530:                toff = sizeof (struct hpux_exec);
        !           531:        else
        !           532: #endif
        !           533:        toff = sizeof (struct exec);
        !           534:        if (vp->v_text && (vp->v_text->x_flag & XTRC))
        !           535:                return (ETXTBSY);
        !           536:        if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
        !           537:            vp->v_usecount != 1) {
        !           538:                register struct file *fp;
        !           539: 
        !           540:                for (fp = file; fp < fileNFILE; fp++) {
        !           541:                        if (fp->f_type == DTYPE_VNODE &&
        !           542:                            fp->f_count > 0 &&
        !           543:                            (struct vnode *)fp->f_data == vp &&
        !           544:                            (fp->f_flag & FWRITE)) {
        !           545:                                return (ETXTBSY);
        !           546:                        }
        !           547:                }
        !           548:        }
        !           549: 
        !           550:        /*
        !           551:         * Compute text and data sizes and make sure not too large.
        !           552:         * NB - Check data and bss separately as they may overflow 
        !           553:         * when summed together.
        !           554:         */
        !           555:        ts = clrnd(btoc(ep->a_text));
        !           556:        ids = clrnd(btoc(ep->a_data));
        !           557:        uds = clrnd(btoc(ep->a_bss));
        !           558:        ds = clrnd(btoc(ep->a_data + ep->a_bss));
        !           559:        ss = clrnd(SSIZE + btoc(nargc));
        !           560:        if (error =
        !           561:            chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss))
        !           562:                return (error);
        !           563: 
        !           564:        /*
        !           565:         * Make sure enough space to start process.
        !           566:         */
        !           567:        u.u_cdmap = zdmap;
        !           568:        u.u_csmap = zdmap;
        !           569:        if (error = swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap))
        !           570:                return (error);
        !           571: 
        !           572:        /*
        !           573:         * At this point, we are committed to the new image!
        !           574:         * Release virtual memory resources of old process, and
        !           575:         * initialize the virtual memory of the new process.
        !           576:         * If we resulted from vfork(), instead wakeup our
        !           577:         * parent who will set SVFDONE when he has taken back
        !           578:         * our resources.
        !           579:         */
        !           580:        if ((p->p_flag & SVFORK) == 0) {
        !           581: #ifdef MAPMEM
        !           582:                if (u.u_mmap && (error = mmexec(p)))
        !           583:                        return (error);
        !           584: #endif
        !           585:                vrelvm();
        !           586:        } else {
        !           587:                p->p_flag &= ~SVFORK;
        !           588:                p->p_flag |= SKEEP;
        !           589:                wakeup((caddr_t)p);
        !           590:                while ((p->p_flag & SVFDONE) == 0)
        !           591:                        sleep((caddr_t)p, PZERO - 1);
        !           592:                p->p_flag &= ~(SVFDONE|SKEEP);
        !           593:        }
        !           594: #ifdef hp300
        !           595:        u.u_pcb.pcb_flags &= ~(PCB_AST|PCB_HPUXMMAP|PCB_HPUXBIN);
        !           596: #ifdef HPUXCOMPAT
        !           597:        /* remember that we were loaded from an HPUX format file */
        !           598:        if (ep->a_mid == MID_HPUX)
        !           599:                u.u_pcb.pcb_flags |= PCB_HPUXBIN;
        !           600: #endif
        !           601: #endif
        !           602:        p->p_flag &= ~(SPAGV|SSEQL|SUANOM|SHPUX);
        !           603:        p->p_flag |= flags | SEXEC;
        !           604:        u.u_dmap = u.u_cdmap;
        !           605:        u.u_smap = u.u_csmap;
        !           606:        vgetvm(ts, ds, ss);
        !           607: 
        !           608:        if ((flags & SPAGV) == 0)
        !           609:                (void) vn_rdwr(UIO_READ, vp,
        !           610:                        (char *)ctob(dptov(p, 0)),
        !           611:                        (int)ep->a_data,
        !           612:                        (off_t)(toff + ep->a_text),
        !           613:                        UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0);
        !           614:        xalloc(vp, ep, toff, cred);
        !           615: #if defined(tahoe)
        !           616:        /*
        !           617:         * Define new keys.
        !           618:         */
        !           619:        if (p->p_textp == 0) {  /* use existing code key if shared */
        !           620:                ckeyrelease(p->p_ckey);
        !           621:                p->p_ckey = getcodekey();
        !           622:        }
        !           623:        mtpr(CCK, p->p_ckey);
        !           624:        dkeyrelease(p->p_dkey);
        !           625:        p->p_dkey = getdatakey();
        !           626:        mtpr(DCK, p->p_dkey);
        !           627: #endif
        !           628:        if ((flags & SPAGV) && p->p_textp)
        !           629:                vinifod(p, (struct fpte *)dptopte(p, 0),
        !           630:                    PG_FTEXT, p->p_textp->x_vptr,
        !           631:                    (long)(1 + ts/CLSIZE), (segsz_t)btoc(ep->a_data));
        !           632: 
        !           633: #if defined(vax) || defined(tahoe)
        !           634:        /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
        !           635:        mtpr(TBIA, 0);
        !           636: #endif
        !           637: #ifdef hp300
        !           638:        TBIAU();
        !           639: #endif
        !           640: #if defined(i386)
        !           641:        tlbflush();
        !           642: #endif
        !           643: 
        !           644:        /*
        !           645:         * set SUID/SGID protections, if no tracing
        !           646:         */
        !           647:        if ((p->p_flag&STRC)==0) {
        !           648:                if (uid != cred->cr_uid || gid != cred->cr_gid)
        !           649:                        u.u_cred = cred = crcopy(cred);
        !           650:                cred->cr_uid = uid;
        !           651:                cred->cr_gid = gid;
        !           652:                p->p_uid = uid;
        !           653:        } else
        !           654:                psignal(p, SIGTRAP);
        !           655:        p->p_svuid = p->p_uid;
        !           656:        p->p_svgid = cred->cr_gid;
        !           657:        u.u_tsize = ts;
        !           658:        u.u_dsize = ds;
        !           659:        u.u_ssize = ss;
        !           660:        u.u_prof.pr_scale = 0;
        !           661: #if defined(tahoe)
        !           662:        u.u_pcb.pcb_savacc.faddr = (float *)NULL;
        !           663: #endif
        !           664:        return (0);
        !           665: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.