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

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

unix.superglobalmegacorp.com

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