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

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

unix.superglobalmegacorp.com

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