Annotation of linux/fs/exec.c, revision 1.1.1.11

1.1.1.2   root        1: /*
                      2:  *  linux/fs/exec.c
                      3:  *
1.1.1.10  root        4:  *  Copyright (C) 1991, 1992  Linus Torvalds
1.1.1.2   root        5:  */
                      6: 
1.1.1.3   root        7: /*
                      8:  * #!-checking implemented by tytso.
                      9:  */
                     10: 
                     11: /*
                     12:  * Demand-loading implemented 01.12.91 - no need to read anything but
                     13:  * the header into memory. The inode of the executable is put into
                     14:  * "current->executable", and page faults do the actual loading. Clean.
                     15:  *
                     16:  * Once more I can proudly say that linux stood up to being changed: it
                     17:  * was less than 2 hours work to get demand-loading completely implemented.
                     18:  */
                     19: 
1.1       root       20: #include <linux/fs.h>
                     21: #include <linux/sched.h>
                     22: #include <linux/kernel.h>
                     23: #include <linux/mm.h>
1.1.1.10  root       24: #include <linux/a.out.h>
                     25: #include <linux/errno.h>
                     26: #include <linux/signal.h>
                     27: #include <linux/string.h>
                     28: #include <linux/stat.h>
                     29: #include <linux/fcntl.h>
                     30: #include <linux/ptrace.h>
                     31: #include <linux/user.h>
                     32: 
1.1       root       33: #include <asm/segment.h>
                     34: 
                     35: extern int sys_exit(int exit_code);
                     36: extern int sys_close(int fd);
                     37: 
                     38: /*
                     39:  * MAX_ARG_PAGES defines the number of pages allocated for arguments
                     40:  * and envelope for the new program. 32 should suffice, this gives
                     41:  * a maximum env+arg of 128kB !
                     42:  */
                     43: #define MAX_ARG_PAGES 32
                     44: 
1.1.1.7   root       45: /*
1.1.1.8   root       46:  * These are the only things you should do on a core-file: use only these
                     47:  * macros to write out all the necessary info.
                     48:  */
                     49: #define DUMP_WRITE(addr,nr) \
                     50: while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump
                     51: 
                     52: #define DUMP_SEEK(offset) \
                     53: if (file.f_op->lseek) { \
                     54:        if (file.f_op->lseek(inode,&file,(offset),0) != (offset)) \
                     55:                goto close_coredump; \
                     56: } else file.f_pos = (offset)           
                     57: 
                     58: /*
                     59:  * Routine writes a core dump image in the current directory.
                     60:  * Currently only a stub-function.
                     61:  *
                     62:  * Note that setuid/setgid files won't make a core-dump if the uid/gid
                     63:  * changed due to the set[u|g]id. It's enforced by the "current->dumpable"
                     64:  * field, which also makes sure the core-dumps won't be recursive if the
                     65:  * dumping of the process results in another error..
                     66:  */
                     67: int core_dump(long signr, struct pt_regs * regs)
                     68: {
                     69:        struct inode * inode = NULL;
                     70:        struct file file;
                     71:        unsigned short fs;
                     72:        int has_dumped = 0;
                     73:        register int dump_start, dump_size;
                     74:        struct user dump;
                     75: 
                     76:        if (!current->dumpable)
                     77:                return 0;
                     78:        current->dumpable = 0;
                     79: /* See if we have enough room to write the upage.  */
                     80:        if(current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE/1024) return 0;
                     81:        __asm__("mov %%fs,%0":"=r" (fs));
                     82:        __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
1.1.1.11! root       83:        if (open_namei("core",O_CREAT | O_WRONLY | O_TRUNC,0600,&inode,NULL)) {
        !            84:                inode = NULL;
1.1.1.8   root       85:                goto end_coredump;
1.1.1.11! root       86:        }
1.1.1.8   root       87:        if (!S_ISREG(inode->i_mode))
                     88:                goto end_coredump;
                     89:        if (!inode->i_op || !inode->i_op->default_file_ops)
                     90:                goto end_coredump;
                     91:        file.f_mode = 3;
                     92:        file.f_flags = 0;
                     93:        file.f_count = 1;
                     94:        file.f_inode = inode;
                     95:        file.f_pos = 0;
                     96:        file.f_reada = 0;
                     97:        file.f_op = inode->i_op->default_file_ops;
                     98:        if (file.f_op->open)
                     99:                if (file.f_op->open(inode,&file))
                    100:                        goto end_coredump;
                    101:        if (!file.f_op->write)
                    102:                goto close_coredump;
                    103:        has_dumped = 1;
1.1.1.11! root      104: /* changed the size calculations - should hopefully work better. lbt */
1.1.1.10  root      105:        dump.magic = CMAGIC;
1.1.1.11! root      106:        dump.start_code = 0;
        !           107:        dump.start_stack = regs->esp & ~(PAGE_SIZE - 1);
        !           108:        dump.u_tsize = ((unsigned long) current->end_code) >> 12;
        !           109:        dump.u_dsize = ((unsigned long) (current->brk + (PAGE_SIZE-1))) >> 12;
        !           110:        dump.u_dsize -= dump.u_tsize;
        !           111:        dump.u_ssize = 0;
        !           112:        if (dump.start_stack < TASK_SIZE)
        !           113:                dump.u_ssize = ((unsigned long) (TASK_SIZE - dump.start_stack)) >> 12;
1.1.1.8   root      114: /* If the size of the dump file exceeds the rlimit, then see what would happen
                    115:    if we wrote the stack, but not the data area.  */
                    116:        if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE/1024 >
                    117:            current->rlim[RLIMIT_CORE].rlim_cur)
                    118:                dump.u_dsize = 0;
                    119: /* Make sure we have enough room to write the stack and data areas. */
                    120:        if ((dump.u_ssize+1) * PAGE_SIZE / 1024 >
                    121:            current->rlim[RLIMIT_CORE].rlim_cur)
                    122:                dump.u_ssize = 0;
                    123:                dump.u_comm = 0;
                    124:        dump.u_ar0 = (struct pt_regs *)(((int)(&dump.regs)) -((int)(&dump)));
                    125:        dump.signal = signr;
                    126:        dump.regs = *regs;
                    127: /* Flag indicating the math stuff is valid. */
                    128:        if (dump.u_fpvalid = current->used_math) {
                    129:                if (last_task_used_math == current)
                    130:                        __asm__("clts ; fnsave %0"::"m" (dump.i387));
                    131:                else
                    132:                        memcpy(&dump.i387,&current->tss.i387,sizeof(dump.i387));
                    133:        };
1.1.1.11! root      134:        __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
1.1.1.8   root      135:        DUMP_WRITE(&dump,sizeof(dump));
                    136:        DUMP_SEEK(sizeof(dump));
                    137:  /* Dump the task struct.  Not be used by gdb, but could be useful */
                    138:        DUMP_WRITE(current,sizeof(*current));
                    139: /* Now dump all of the user data.  Include malloced stuff as well */
                    140:        DUMP_SEEK(PAGE_SIZE);
                    141: /* now we start writing out the user space info */
                    142:        __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x17));
                    143: /* Dump the data area */
                    144:        if (dump.u_dsize != 0) {
1.1.1.11! root      145:                dump_start = dump.u_tsize << 12;
        !           146:                dump_size = dump.u_dsize << 12;
1.1.1.8   root      147:                DUMP_WRITE(dump_start,dump_size);
                    148:        };
                    149: /* Now prepare to dump the stack area */
                    150:        if (dump.u_ssize != 0) {
1.1.1.11! root      151:                dump_start = dump.start_stack;
        !           152:                dump_size = dump.u_ssize << 12;
1.1.1.8   root      153:                DUMP_WRITE(dump_start,dump_size);
                    154:        };
                    155: close_coredump:
                    156:        if (file.f_op->release)
                    157:                file.f_op->release(inode,&file);
                    158: end_coredump:
                    159:        __asm__("mov %0,%%fs"::"r" (fs));
                    160:        iput(inode);
                    161:        return has_dumped;
                    162: }
                    163: 
                    164: /*
1.1.1.7   root      165:  * Note that a shared library must be both readable and executable due to
                    166:  * security reasons.
                    167:  *
                    168:  * Also note that we take the address to load from from the file itself.
                    169:  */
1.1.1.4   root      170: int sys_uselib(const char * library)
                    171: {
1.1.1.7   root      172: #define libnum (current->numlibraries)
1.1.1.5   root      173:        struct inode * inode;
1.1.1.7   root      174:        struct buffer_head * bh;
                    175:        struct exec ex;
1.1.1.11! root      176:        int error;
1.1.1.4   root      177: 
1.1.1.11! root      178:        if (!library || get_limit(0x17) != TASK_SIZE)
1.1.1.4   root      179:                return -EINVAL;
1.1.1.7   root      180:        if ((libnum >= MAX_SHARED_LIBS) || (libnum < 0))
                    181:                return -EINVAL;
1.1.1.11! root      182:        error = namei(library,&inode);
        !           183:        if (error)
        !           184:                return error;
1.1.1.10  root      185:        if (!inode->i_sb || !S_ISREG(inode->i_mode) || !permission(inode,MAY_READ)) {
1.1.1.7   root      186:                iput(inode);
                    187:                return -EACCES;
                    188:        }
1.1.1.10  root      189:        if (!(bh = bread(inode->i_dev,bmap(inode,0),inode->i_sb->s_blocksize))) {
1.1.1.7   root      190:                iput(inode);
                    191:                return -EACCES;
                    192:        }
1.1.1.10  root      193:        if (!IS_RDONLY(inode)) {
                    194:                inode->i_atime = CURRENT_TIME;
                    195:                inode->i_dirt = 1;
                    196:        }
1.1.1.7   root      197:        ex = *(struct exec *) bh->b_data;
                    198:        brelse(bh);
                    199:        if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||
                    200:                ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
                    201:                inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
                    202:                iput(inode);
                    203:                return -ENOEXEC;
                    204:        }
                    205:        current->libraries[libnum].library = inode;
                    206:        current->libraries[libnum].start = ex.a_entry;
                    207:        current->libraries[libnum].length = (ex.a_data+ex.a_text+0xfff) & 0xfffff000;
1.1.1.11! root      208:        current->libraries[libnum].bss = (ex.a_bss+0xfff) & 0xfffff000;
1.1.1.7   root      209: #if 0
                    210:        printk("Loaded library %d at %08x, length %08x\n",
                    211:                libnum,
                    212:                current->libraries[libnum].start,
                    213:                current->libraries[libnum].length);
                    214: #endif
                    215:        libnum++;
1.1.1.4   root      216:        return 0;
1.1.1.7   root      217: #undef libnum
1.1.1.4   root      218: }
                    219: 
1.1       root      220: /*
                    221:  * create_tables() parses the env- and arg-strings in new user
                    222:  * memory and creates the pointer tables from them, and puts their
                    223:  * addresses on the "stack", returning the new stack pointer value.
                    224:  */
                    225: static unsigned long * create_tables(char * p,int argc,int envc)
                    226: {
                    227:        unsigned long *argv,*envp;
                    228:        unsigned long * sp;
                    229: 
                    230:        sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
                    231:        sp -= envc+1;
                    232:        envp = sp;
                    233:        sp -= argc+1;
                    234:        argv = sp;
                    235:        put_fs_long((unsigned long)envp,--sp);
                    236:        put_fs_long((unsigned long)argv,--sp);
                    237:        put_fs_long((unsigned long)argc,--sp);
                    238:        while (argc-->0) {
                    239:                put_fs_long((unsigned long) p,argv++);
                    240:                while (get_fs_byte(p++)) /* nothing */ ;
                    241:        }
                    242:        put_fs_long(0,argv);
                    243:        while (envc-->0) {
                    244:                put_fs_long((unsigned long) p,envp++);
                    245:                while (get_fs_byte(p++)) /* nothing */ ;
                    246:        }
                    247:        put_fs_long(0,envp);
                    248:        return sp;
                    249: }
                    250: 
                    251: /*
                    252:  * count() counts the number of arguments/envelopes
                    253:  */
                    254: static int count(char ** argv)
                    255: {
                    256:        int i=0;
                    257:        char ** tmp;
                    258: 
                    259:        if (tmp = argv)
                    260:                while (get_fs_long((unsigned long *) (tmp++)))
                    261:                        i++;
                    262: 
                    263:        return i;
                    264: }
                    265: 
                    266: /*
                    267:  * 'copy_string()' copies argument/envelope strings from user
                    268:  * memory to free pages in kernel mem. These are in a format ready
                    269:  * to be put directly into the top of new user memory.
1.1.1.2   root      270:  *
                    271:  * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies
                    272:  * whether the string and the string array are from user or kernel segments:
                    273:  * 
                    274:  * from_kmem     argv *        argv **
                    275:  *    0          user space    user space
                    276:  *    1          kernel space  user space
                    277:  *    2          kernel space  kernel space
                    278:  * 
                    279:  * We do this by playing games with the fs segment register.  Since it
                    280:  * it is expensive to load a segment register, we try to avoid calling
                    281:  * set_fs() unless we absolutely have to.
1.1       root      282:  */
                    283: static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
1.1.1.2   root      284:                unsigned long p, int from_kmem)
1.1       root      285: {
1.1.1.9   root      286:        char *tmp, *pag = NULL;
1.1.1.2   root      287:        int len, offset = 0;
                    288:        unsigned long old_fs, new_fs;
                    289: 
                    290:        if (!p)
                    291:                return 0;       /* bullet-proofing */
                    292:        new_fs = get_ds();
                    293:        old_fs = get_fs();
                    294:        if (from_kmem==2)
                    295:                set_fs(new_fs);
1.1       root      296:        while (argc-- > 0) {
1.1.1.2   root      297:                if (from_kmem == 1)
                    298:                        set_fs(new_fs);
                    299:                if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc)))
1.1       root      300:                        panic("argc is wrong");
1.1.1.2   root      301:                if (from_kmem == 1)
                    302:                        set_fs(old_fs);
1.1       root      303:                len=0;          /* remember zero-padding */
                    304:                do {
                    305:                        len++;
                    306:                } while (get_fs_byte(tmp++));
1.1.1.5   root      307:                if (p < len) {  /* this shouldn't happen - 128kB */
1.1.1.2   root      308:                        set_fs(old_fs);
1.1       root      309:                        return 0;
                    310:                }
1.1.1.2   root      311:                while (len) {
                    312:                        --p; --tmp; --len;
                    313:                        if (--offset < 0) {
                    314:                                offset = p % PAGE_SIZE;
                    315:                                if (from_kmem==2)
                    316:                                        set_fs(old_fs);
                    317:                                if (!(pag = (char *) page[p/PAGE_SIZE]) &&
                    318:                                    !(pag = (char *) page[p/PAGE_SIZE] =
1.1.1.10  root      319:                                      (unsigned long *) get_free_page(GFP_USER))) 
1.1.1.2   root      320:                                        return 0;
                    321:                                if (from_kmem==2)
                    322:                                        set_fs(new_fs);
                    323: 
                    324:                        }
                    325:                        *(pag + offset) = get_fs_byte(tmp);
                    326:                }
1.1       root      327:        }
1.1.1.2   root      328:        if (from_kmem==2)
                    329:                set_fs(old_fs);
1.1       root      330:        return p;
                    331: }
                    332: 
                    333: static unsigned long change_ldt(unsigned long text_size,unsigned long * page)
                    334: {
                    335:        unsigned long code_limit,data_limit,code_base,data_base;
                    336:        int i;
                    337: 
1.1.1.4   root      338:        code_limit = TASK_SIZE;
                    339:        data_limit = TASK_SIZE;
1.1.1.11! root      340:        code_base = data_base = 0;
        !           341:        current->start_code = code_base;
1.1       root      342:        set_base(current->ldt[1],code_base);
                    343:        set_limit(current->ldt[1],code_limit);
                    344:        set_base(current->ldt[2],data_base);
                    345:        set_limit(current->ldt[2],data_limit);
                    346: /* make sure fs points to the NEW data segment */
                    347:        __asm__("pushl $0x17\n\tpop %%fs"::);
1.1.1.11! root      348:        data_base += data_limit;
1.1       root      349:        for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
                    350:                data_base -= PAGE_SIZE;
                    351:                if (page[i])
1.1.1.11! root      352:                        put_dirty_page(current,page[i],data_base);
1.1       root      353:        }
                    354:        return data_limit;
                    355: }
                    356: 
1.1.1.7   root      357: static void read_omagic(struct inode *inode, int bytes)
                    358: {
                    359:        struct buffer_head *bh;
                    360:        int n, blkno, blk = 0;
                    361:        char *dest = (char *) 0;
1.1.1.10  root      362:        unsigned int block_size;
1.1.1.7   root      363: 
1.1.1.10  root      364:        block_size = 1024;
                    365:        if (inode->i_sb)
                    366:                block_size = inode->i_sb->s_blocksize;
1.1.1.7   root      367:        while (bytes > 0) {
                    368:                if (!(blkno = bmap(inode, blk)))
                    369:                        sys_exit(-1);
1.1.1.10  root      370:                if (!(bh = bread(inode->i_dev, blkno, block_size)))
1.1.1.7   root      371:                        sys_exit(-1);
1.1.1.10  root      372:                n = (blk ? block_size : block_size - sizeof(struct exec));
1.1.1.7   root      373:                if (bytes < n)
                    374:                        n = bytes;
                    375: 
                    376:                memcpy_tofs(dest, (blk ? bh->b_data :
                    377:                                bh->b_data + sizeof(struct exec)), n);
                    378:                brelse(bh);
                    379:                ++blk;
                    380:                dest += n;
                    381:                bytes -= n;
                    382:        }
                    383:        iput(inode);
                    384:        current->executable = NULL;
                    385: }
                    386: 
1.1       root      387: /*
                    388:  * 'do_execve()' executes a new program.
1.1.1.4   root      389:  *
                    390:  * NOTE! We leave 4MB free at the top of the data-area for a loadable
                    391:  * library.
1.1       root      392:  */
                    393: int do_execve(unsigned long * eip,long tmp,char * filename,
                    394:        char ** argv, char ** envp)
                    395: {
1.1.1.5   root      396:        struct inode * inode;
1.1       root      397:        struct buffer_head * bh;
                    398:        struct exec ex;
                    399:        unsigned long page[MAX_ARG_PAGES];
                    400:        int i,argc,envc;
1.1.1.2   root      401:        int e_uid, e_gid;
                    402:        int retval;
                    403:        int sh_bang = 0;
                    404:        unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4;
1.1.1.6   root      405:        int ch;
1.1       root      406: 
                    407:        if ((0xffff & eip[1]) != 0x000f)
                    408:                panic("execve called from supervisor mode");
                    409:        for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
                    410:                page[i]=0;
1.1.1.11! root      411:        retval = namei(filename,&inode);        /* get executable inode */
        !           412:        if (retval)
        !           413:                return retval;
1.1.1.2   root      414:        argc = count(argv);
                    415:        envc = count(envp);
                    416:        
                    417: restart_interp:
1.1       root      418:        if (!S_ISREG(inode->i_mode)) {  /* must be regular file */
1.1.1.2   root      419:                retval = -EACCES;
                    420:                goto exec_error2;
1.1       root      421:        }
1.1.1.11! root      422:        if (IS_NOEXEC(inode)) {         /* FS mustn't be mounted noexec */
1.1.1.10  root      423:                retval = -EPERM;
                    424:                goto exec_error2;
                    425:        }
                    426:        if (!inode->i_sb) {
                    427:                retval = -EACCES;
                    428:                goto exec_error2;
                    429:        }
1.1       root      430:        i = inode->i_mode;
1.1.1.10  root      431:        if (IS_NOSUID(inode) && (((i & S_ISUID) && inode->i_uid != current->
                    432:            euid) || ((i & S_ISGID) && inode->i_gid != current->egid)) &&
                    433:            !suser()) {
                    434:                retval = -EPERM;
                    435:                goto exec_error2;
                    436:        }
1.1.1.5   root      437:        /* make sure we don't let suid, sgid files be ptraced. */
                    438:        if (current->flags & PF_PTRACED) {
                    439:                e_uid = current->euid;
                    440:                e_gid = current->egid;
                    441:        } else {
                    442:                e_uid = (i & S_ISUID) ? inode->i_uid : current->euid;
                    443:                e_gid = (i & S_ISGID) ? inode->i_gid : current->egid;
                    444:        }
1.1.1.2   root      445:        if (current->euid == inode->i_uid)
                    446:                i >>= 6;
1.1.1.4   root      447:        else if (in_group_p(inode->i_gid))
1.1.1.2   root      448:                i >>= 3;
                    449:        if (!(i & 1) &&
                    450:            !((inode->i_mode & 0111) && suser())) {
1.1.1.5   root      451:                retval = -EACCES;
1.1.1.2   root      452:                goto exec_error2;
1.1       root      453:        }
1.1.1.10  root      454:        if (!(bh = bread(inode->i_dev,bmap(inode,0),inode->i_sb->s_blocksize))) {
1.1.1.2   root      455:                retval = -EACCES;
                    456:                goto exec_error2;
1.1       root      457:        }
1.1.1.10  root      458:        if (!IS_RDONLY(inode)) {
                    459:                inode->i_atime = CURRENT_TIME;
                    460:                inode->i_dirt = 1;
                    461:        }
1.1       root      462:        ex = *((struct exec *) bh->b_data);     /* read exec-header */
1.1.1.2   root      463:        if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {
                    464:                /*
                    465:                 * This section does the #! interpretation.
                    466:                 * Sorta complicated, but hopefully it will work.  -TYT
                    467:                 */
                    468: 
1.1.1.4   root      469:                char buf[128], *cp, *interp, *i_name, *i_arg;
1.1.1.2   root      470:                unsigned long old_fs;
                    471: 
1.1.1.4   root      472:                strncpy(buf, bh->b_data+2, 127);
1.1.1.2   root      473:                brelse(bh);
                    474:                iput(inode);
1.1.1.4   root      475:                buf[127] = '\0';
1.1.1.2   root      476:                if (cp = strchr(buf, '\n')) {
                    477:                        *cp = '\0';
                    478:                        for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++);
                    479:                }
                    480:                if (!cp || *cp == '\0') {
                    481:                        retval = -ENOEXEC; /* No interpreter name found */
                    482:                        goto exec_error1;
                    483:                }
                    484:                interp = i_name = cp;
                    485:                i_arg = 0;
                    486:                for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
                    487:                        if (*cp == '/')
                    488:                                i_name = cp+1;
                    489:                }
                    490:                if (*cp) {
                    491:                        *cp++ = '\0';
                    492:                        i_arg = cp;
                    493:                }
                    494:                /*
                    495:                 * OK, we've parsed out the interpreter name and
                    496:                 * (optional) argument.
                    497:                 */
                    498:                if (sh_bang++ == 0) {
                    499:                        p = copy_strings(envc, envp, page, p, 0);
                    500:                        p = copy_strings(--argc, argv+1, page, p, 0);
                    501:                }
                    502:                /*
                    503:                 * Splice in (1) the interpreter's name for argv[0]
                    504:                 *           (2) (optional) argument to interpreter
                    505:                 *           (3) filename of shell script
                    506:                 *
                    507:                 * This is done in reverse order, because of how the
                    508:                 * user environment and arguments are stored.
                    509:                 */
                    510:                p = copy_strings(1, &filename, page, p, 1);
                    511:                argc++;
                    512:                if (i_arg) {
                    513:                        p = copy_strings(1, &i_arg, page, p, 2);
                    514:                        argc++;
                    515:                }
                    516:                p = copy_strings(1, &i_name, page, p, 2);
                    517:                argc++;
                    518:                if (!p) {
                    519:                        retval = -ENOMEM;
                    520:                        goto exec_error1;
                    521:                }
                    522:                /*
                    523:                 * OK, now restart the process with the interpreter's inode.
                    524:                 */
                    525:                old_fs = get_fs();
                    526:                set_fs(get_ds());
1.1.1.11! root      527:                retval = namei(interp,&inode);
1.1.1.2   root      528:                set_fs(old_fs);
1.1.1.11! root      529:                if (retval)
        !           530:                        goto exec_error1;
1.1.1.2   root      531:                goto restart_interp;
                    532:        }
1.1       root      533:        brelse(bh);
1.1.1.7   root      534:        if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) ||
                    535:                ex.a_trsize || ex.a_drsize ||
1.1       root      536:                ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
                    537:                inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
1.1.1.2   root      538:                retval = -ENOEXEC;
                    539:                goto exec_error2;
1.1       root      540:        }
1.1.1.7   root      541:        if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) {
1.1.1.2   root      542:                printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename);
                    543:                retval = -ENOEXEC;
                    544:                goto exec_error2;
                    545:        }
                    546:        if (!sh_bang) {
                    547:                p = copy_strings(envc,envp,page,p,0);
                    548:                p = copy_strings(argc,argv,page,p,0);
                    549:                if (!p) {
                    550:                        retval = -ENOMEM;
                    551:                        goto exec_error2;
                    552:                }
1.1       root      553:        }
                    554: /* OK, This is the point of no return */
1.1.1.8   root      555:        current->dumpable = 1;
1.1.1.6   root      556:        for (i=0; (ch = get_fs_byte(filename++)) != '\0';)
                    557:                if (ch == '/')
                    558:                        i = 0;
                    559:                else
                    560:                        if (i < 8)
                    561:                                current->comm[i++] = ch;
                    562:        if (i < 8)
                    563:                current->comm[i] = '\0';
1.1.1.3   root      564:        if (current->executable)
                    565:                iput(current->executable);
1.1.1.7   root      566:        i = current->numlibraries;
                    567:        while (i-- > 0) {
                    568:                iput(current->libraries[i].library);
                    569:                current->libraries[i].library = NULL;
                    570:        }
1.1.1.8   root      571:        if (e_uid != current->euid || e_gid != current->egid ||
                    572:            !permission(inode,MAY_READ))
                    573:                current->dumpable = 0;
1.1.1.7   root      574:        current->numlibraries = 0;
1.1.1.3   root      575:        current->executable = inode;
1.1.1.4   root      576:        current->signal = 0;
                    577:        for (i=0 ; i<32 ; i++) {
                    578:                current->sigaction[i].sa_mask = 0;
                    579:                current->sigaction[i].sa_flags = 0;
                    580:                if (current->sigaction[i].sa_handler != SIG_IGN)
                    581:                        current->sigaction[i].sa_handler = NULL;
                    582:        }
1.1       root      583:        for (i=0 ; i<NR_OPEN ; i++)
                    584:                if ((current->close_on_exec>>i)&1)
                    585:                        sys_close(i);
                    586:        current->close_on_exec = 0;
1.1.1.11! root      587:        clear_page_tables(current);
1.1       root      588:        if (last_task_used_math == current)
                    589:                last_task_used_math = NULL;
                    590:        current->used_math = 0;
1.1.1.4   root      591:        p += change_ldt(ex.a_text,page);
1.1.1.11! root      592:        p -= MAX_ARG_PAGES*PAGE_SIZE;
1.1       root      593:        p = (unsigned long) create_tables((char *)p,argc,envc);
                    594:        current->brk = ex.a_bss +
                    595:                (current->end_data = ex.a_data +
                    596:                (current->end_code = ex.a_text));
1.1.1.5   root      597:        current->start_stack = p;
1.1.1.11! root      598:        current->rss = (TASK_SIZE - p + PAGE_SIZE-1) / PAGE_SIZE;
1.1.1.4   root      599:        current->suid = current->euid = e_uid;
                    600:        current->sgid = current->egid = e_gid;
1.1.1.7   root      601:        if (N_MAGIC(ex) == OMAGIC)
                    602:                read_omagic(inode, ex.a_text+ex.a_data);
1.1       root      603:        eip[0] = ex.a_entry;            /* eip, magic happens :-) */
                    604:        eip[3] = p;                     /* stack pointer */
1.1.1.5   root      605:        if (current->flags & PF_PTRACED)
1.1.1.8   root      606:                send_sig(SIGTRAP, current, 0);
1.1       root      607:        return 0;
1.1.1.2   root      608: exec_error2:
                    609:        iput(inode);
                    610: exec_error1:
                    611:        for (i=0 ; i<MAX_ARG_PAGES ; i++)
                    612:                free_page(page[i]);
                    613:        return(retval);
1.1       root      614: }

unix.superglobalmegacorp.com

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