|
|
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.7 ! root 22: #include <linux/string.h>
1.1 root 23: #include <sys/stat.h>
24: #include <a.out.h>
25:
26: #include <linux/fs.h>
27: #include <linux/sched.h>
28: #include <linux/kernel.h>
29: #include <linux/mm.h>
30: #include <asm/segment.h>
31:
32: extern int sys_exit(int exit_code);
33: extern int sys_close(int fd);
34:
35: /*
36: * MAX_ARG_PAGES defines the number of pages allocated for arguments
37: * and envelope for the new program. 32 should suffice, this gives
38: * a maximum env+arg of 128kB !
39: */
40: #define MAX_ARG_PAGES 32
41:
1.1.1.7 ! root 42: /*
! 43: * Note that a shared library must be both readable and executable due to
! 44: * security reasons.
! 45: *
! 46: * Also note that we take the address to load from from the file itself.
! 47: */
1.1.1.4 root 48: int sys_uselib(const char * library)
49: {
1.1.1.7 ! root 50: #define libnum (current->numlibraries)
1.1.1.5 root 51: struct inode * inode;
1.1.1.7 ! root 52: struct buffer_head * bh;
! 53: struct exec ex;
1.1.1.4 root 54:
55: if (get_limit(0x17) != TASK_SIZE)
56: return -EINVAL;
1.1.1.7 ! root 57: if ((libnum >= MAX_SHARED_LIBS) || (libnum < 0))
! 58: return -EINVAL;
! 59: if (library)
! 60: inode = namei(library);
! 61: else
1.1.1.4 root 62: inode = NULL;
1.1.1.7 ! root 63: if (!inode)
! 64: return -ENOENT;
! 65: if (!S_ISREG(inode->i_mode) || !permission(inode,MAY_READ)) {
! 66: iput(inode);
! 67: return -EACCES;
! 68: }
! 69: if (!(bh = bread(inode->i_dev,inode->i_data[0]))) {
! 70: iput(inode);
! 71: return -EACCES;
! 72: }
! 73: ex = *(struct exec *) bh->b_data;
! 74: brelse(bh);
! 75: if (N_MAGIC(ex) != ZMAGIC || ex.a_trsize || ex.a_drsize ||
! 76: ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
! 77: inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
! 78: iput(inode);
! 79: return -ENOEXEC;
! 80: }
! 81: current->libraries[libnum].library = inode;
! 82: current->libraries[libnum].start = ex.a_entry;
! 83: current->libraries[libnum].length = (ex.a_data+ex.a_text+0xfff) & 0xfffff000;
! 84: #if 0
! 85: printk("Loaded library %d at %08x, length %08x\n",
! 86: libnum,
! 87: current->libraries[libnum].start,
! 88: current->libraries[libnum].length);
! 89: #endif
! 90: libnum++;
1.1.1.4 root 91: return 0;
1.1.1.7 ! root 92: #undef libnum
1.1.1.4 root 93: }
94:
1.1 root 95: /*
96: * create_tables() parses the env- and arg-strings in new user
97: * memory and creates the pointer tables from them, and puts their
98: * addresses on the "stack", returning the new stack pointer value.
99: */
100: static unsigned long * create_tables(char * p,int argc,int envc)
101: {
102: unsigned long *argv,*envp;
103: unsigned long * sp;
104:
105: sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
106: sp -= envc+1;
107: envp = sp;
108: sp -= argc+1;
109: argv = sp;
110: put_fs_long((unsigned long)envp,--sp);
111: put_fs_long((unsigned long)argv,--sp);
112: put_fs_long((unsigned long)argc,--sp);
113: while (argc-->0) {
114: put_fs_long((unsigned long) p,argv++);
115: while (get_fs_byte(p++)) /* nothing */ ;
116: }
117: put_fs_long(0,argv);
118: while (envc-->0) {
119: put_fs_long((unsigned long) p,envp++);
120: while (get_fs_byte(p++)) /* nothing */ ;
121: }
122: put_fs_long(0,envp);
123: return sp;
124: }
125:
126: /*
127: * count() counts the number of arguments/envelopes
128: */
129: static int count(char ** argv)
130: {
131: int i=0;
132: char ** tmp;
133:
134: if (tmp = argv)
135: while (get_fs_long((unsigned long *) (tmp++)))
136: i++;
137:
138: return i;
139: }
140:
141: /*
142: * 'copy_string()' copies argument/envelope strings from user
143: * memory to free pages in kernel mem. These are in a format ready
144: * to be put directly into the top of new user memory.
1.1.1.2 root 145: *
146: * Modified by TYT, 11/24/91 to add the from_kmem argument, which specifies
147: * whether the string and the string array are from user or kernel segments:
148: *
149: * from_kmem argv * argv **
150: * 0 user space user space
151: * 1 kernel space user space
152: * 2 kernel space kernel space
153: *
154: * We do this by playing games with the fs segment register. Since it
155: * it is expensive to load a segment register, we try to avoid calling
156: * set_fs() unless we absolutely have to.
1.1 root 157: */
158: static unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
1.1.1.2 root 159: unsigned long p, int from_kmem)
1.1 root 160: {
1.1.1.2 root 161: char *tmp, *pag;
162: int len, offset = 0;
163: unsigned long old_fs, new_fs;
164:
165: if (!p)
166: return 0; /* bullet-proofing */
167: new_fs = get_ds();
168: old_fs = get_fs();
169: if (from_kmem==2)
170: set_fs(new_fs);
1.1 root 171: while (argc-- > 0) {
1.1.1.2 root 172: if (from_kmem == 1)
173: set_fs(new_fs);
174: if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc)))
1.1 root 175: panic("argc is wrong");
1.1.1.2 root 176: if (from_kmem == 1)
177: set_fs(old_fs);
1.1 root 178: len=0; /* remember zero-padding */
179: do {
180: len++;
181: } while (get_fs_byte(tmp++));
1.1.1.5 root 182: if (p < len) { /* this shouldn't happen - 128kB */
1.1.1.2 root 183: set_fs(old_fs);
1.1 root 184: return 0;
185: }
1.1.1.2 root 186: while (len) {
187: --p; --tmp; --len;
188: if (--offset < 0) {
189: offset = p % PAGE_SIZE;
190: if (from_kmem==2)
191: set_fs(old_fs);
192: if (!(pag = (char *) page[p/PAGE_SIZE]) &&
193: !(pag = (char *) page[p/PAGE_SIZE] =
194: (unsigned long *) get_free_page()))
195: return 0;
196: if (from_kmem==2)
197: set_fs(new_fs);
198:
199: }
200: *(pag + offset) = get_fs_byte(tmp);
201: }
1.1 root 202: }
1.1.1.2 root 203: if (from_kmem==2)
204: set_fs(old_fs);
1.1 root 205: return p;
206: }
207:
208: static unsigned long change_ldt(unsigned long text_size,unsigned long * page)
209: {
210: unsigned long code_limit,data_limit,code_base,data_base;
211: int i;
212:
1.1.1.4 root 213: code_limit = TASK_SIZE;
214: data_limit = TASK_SIZE;
1.1 root 215: code_base = get_base(current->ldt[1]);
216: data_base = code_base;
217: set_base(current->ldt[1],code_base);
218: set_limit(current->ldt[1],code_limit);
219: set_base(current->ldt[2],data_base);
220: set_limit(current->ldt[2],data_limit);
221: /* make sure fs points to the NEW data segment */
222: __asm__("pushl $0x17\n\tpop %%fs"::);
1.1.1.4 root 223: data_base += data_limit - LIBRARY_SIZE;
1.1 root 224: for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
225: data_base -= PAGE_SIZE;
226: if (page[i])
1.1.1.4 root 227: put_dirty_page(page[i],data_base);
1.1 root 228: }
229: return data_limit;
230: }
231:
1.1.1.7 ! root 232: static void read_omagic(struct inode *inode, int bytes)
! 233: {
! 234: struct buffer_head *bh;
! 235: int n, blkno, blk = 0;
! 236: char *dest = (char *) 0;
! 237:
! 238: while (bytes > 0) {
! 239: if (!(blkno = bmap(inode, blk)))
! 240: sys_exit(-1);
! 241: if (!(bh = bread(inode->i_dev, blkno)))
! 242: sys_exit(-1);
! 243: n = (blk ? BLOCK_SIZE : BLOCK_SIZE - sizeof(struct exec));
! 244: if (bytes < n)
! 245: n = bytes;
! 246:
! 247: memcpy_tofs(dest, (blk ? bh->b_data :
! 248: bh->b_data + sizeof(struct exec)), n);
! 249: brelse(bh);
! 250: ++blk;
! 251: dest += n;
! 252: bytes -= n;
! 253: }
! 254: iput(inode);
! 255: current->executable = NULL;
! 256: }
! 257:
1.1 root 258: /*
259: * 'do_execve()' executes a new program.
1.1.1.4 root 260: *
261: * NOTE! We leave 4MB free at the top of the data-area for a loadable
262: * library.
1.1 root 263: */
264: int do_execve(unsigned long * eip,long tmp,char * filename,
265: char ** argv, char ** envp)
266: {
1.1.1.5 root 267: struct inode * inode;
1.1 root 268: struct buffer_head * bh;
269: struct exec ex;
270: unsigned long page[MAX_ARG_PAGES];
271: int i,argc,envc;
1.1.1.2 root 272: int e_uid, e_gid;
273: int retval;
274: int sh_bang = 0;
275: unsigned long p=PAGE_SIZE*MAX_ARG_PAGES-4;
1.1.1.6 root 276: int ch;
1.1 root 277:
278: if ((0xffff & eip[1]) != 0x000f)
279: panic("execve called from supervisor mode");
280: for (i=0 ; i<MAX_ARG_PAGES ; i++) /* clear page-table */
281: page[i]=0;
282: if (!(inode=namei(filename))) /* get executables inode */
283: return -ENOENT;
1.1.1.2 root 284: argc = count(argv);
285: envc = count(envp);
286:
287: restart_interp:
1.1 root 288: if (!S_ISREG(inode->i_mode)) { /* must be regular file */
1.1.1.2 root 289: retval = -EACCES;
290: goto exec_error2;
1.1 root 291: }
292: i = inode->i_mode;
1.1.1.5 root 293: /* make sure we don't let suid, sgid files be ptraced. */
294: if (current->flags & PF_PTRACED) {
295: e_uid = current->euid;
296: e_gid = current->egid;
297: } else {
298: e_uid = (i & S_ISUID) ? inode->i_uid : current->euid;
299: e_gid = (i & S_ISGID) ? inode->i_gid : current->egid;
300: }
1.1.1.2 root 301: if (current->euid == inode->i_uid)
302: i >>= 6;
1.1.1.4 root 303: else if (in_group_p(inode->i_gid))
1.1.1.2 root 304: i >>= 3;
305: if (!(i & 1) &&
306: !((inode->i_mode & 0111) && suser())) {
1.1.1.5 root 307: retval = -EACCES;
1.1.1.2 root 308: goto exec_error2;
1.1 root 309: }
1.1.1.5 root 310: if (!(bh = bread(inode->i_dev,inode->i_data[0]))) {
1.1.1.2 root 311: retval = -EACCES;
312: goto exec_error2;
1.1 root 313: }
314: ex = *((struct exec *) bh->b_data); /* read exec-header */
1.1.1.2 root 315: if ((bh->b_data[0] == '#') && (bh->b_data[1] == '!') && (!sh_bang)) {
316: /*
317: * This section does the #! interpretation.
318: * Sorta complicated, but hopefully it will work. -TYT
319: */
320:
1.1.1.4 root 321: char buf[128], *cp, *interp, *i_name, *i_arg;
1.1.1.2 root 322: unsigned long old_fs;
323:
1.1.1.4 root 324: strncpy(buf, bh->b_data+2, 127);
1.1.1.2 root 325: brelse(bh);
326: iput(inode);
1.1.1.4 root 327: buf[127] = '\0';
1.1.1.2 root 328: if (cp = strchr(buf, '\n')) {
329: *cp = '\0';
330: for (cp = buf; (*cp == ' ') || (*cp == '\t'); cp++);
331: }
332: if (!cp || *cp == '\0') {
333: retval = -ENOEXEC; /* No interpreter name found */
334: goto exec_error1;
335: }
336: interp = i_name = cp;
337: i_arg = 0;
338: for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
339: if (*cp == '/')
340: i_name = cp+1;
341: }
342: if (*cp) {
343: *cp++ = '\0';
344: i_arg = cp;
345: }
346: /*
347: * OK, we've parsed out the interpreter name and
348: * (optional) argument.
349: */
350: if (sh_bang++ == 0) {
351: p = copy_strings(envc, envp, page, p, 0);
352: p = copy_strings(--argc, argv+1, page, p, 0);
353: }
354: /*
355: * Splice in (1) the interpreter's name for argv[0]
356: * (2) (optional) argument to interpreter
357: * (3) filename of shell script
358: *
359: * This is done in reverse order, because of how the
360: * user environment and arguments are stored.
361: */
362: p = copy_strings(1, &filename, page, p, 1);
363: argc++;
364: if (i_arg) {
365: p = copy_strings(1, &i_arg, page, p, 2);
366: argc++;
367: }
368: p = copy_strings(1, &i_name, page, p, 2);
369: argc++;
370: if (!p) {
371: retval = -ENOMEM;
372: goto exec_error1;
373: }
374: /*
375: * OK, now restart the process with the interpreter's inode.
376: */
377: old_fs = get_fs();
378: set_fs(get_ds());
379: if (!(inode=namei(interp))) { /* get executables inode */
380: set_fs(old_fs);
381: retval = -ENOENT;
382: goto exec_error1;
383: }
384: set_fs(old_fs);
385: goto restart_interp;
386: }
1.1 root 387: brelse(bh);
1.1.1.7 ! root 388: if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC) ||
! 389: ex.a_trsize || ex.a_drsize ||
1.1 root 390: ex.a_text+ex.a_data+ex.a_bss>0x3000000 ||
391: inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
1.1.1.2 root 392: retval = -ENOEXEC;
393: goto exec_error2;
1.1 root 394: }
1.1.1.7 ! root 395: if (N_TXTOFF(ex) != BLOCK_SIZE && N_MAGIC(ex) != OMAGIC) {
1.1.1.2 root 396: printk("%s: N_TXTOFF != BLOCK_SIZE. See a.out.h.", filename);
397: retval = -ENOEXEC;
398: goto exec_error2;
399: }
400: if (!sh_bang) {
401: p = copy_strings(envc,envp,page,p,0);
402: p = copy_strings(argc,argv,page,p,0);
403: if (!p) {
404: retval = -ENOMEM;
405: goto exec_error2;
406: }
1.1 root 407: }
408: /* OK, This is the point of no return */
1.1.1.6 root 409: for (i=0; (ch = get_fs_byte(filename++)) != '\0';)
410: if (ch == '/')
411: i = 0;
412: else
413: if (i < 8)
414: current->comm[i++] = ch;
415: if (i < 8)
416: current->comm[i] = '\0';
1.1.1.3 root 417: if (current->executable)
418: iput(current->executable);
1.1.1.7 ! root 419: i = current->numlibraries;
! 420: while (i-- > 0) {
! 421: iput(current->libraries[i].library);
! 422: current->libraries[i].library = NULL;
! 423: }
! 424: current->numlibraries = 0;
1.1.1.3 root 425: current->executable = inode;
1.1.1.4 root 426: current->signal = 0;
427: for (i=0 ; i<32 ; i++) {
428: current->sigaction[i].sa_mask = 0;
429: current->sigaction[i].sa_flags = 0;
430: if (current->sigaction[i].sa_handler != SIG_IGN)
431: current->sigaction[i].sa_handler = NULL;
432: }
1.1 root 433: for (i=0 ; i<NR_OPEN ; i++)
434: if ((current->close_on_exec>>i)&1)
435: sys_close(i);
436: current->close_on_exec = 0;
437: free_page_tables(get_base(current->ldt[1]),get_limit(0x0f));
438: free_page_tables(get_base(current->ldt[2]),get_limit(0x17));
439: if (last_task_used_math == current)
440: last_task_used_math = NULL;
441: current->used_math = 0;
1.1.1.4 root 442: p += change_ldt(ex.a_text,page);
443: p -= LIBRARY_SIZE + MAX_ARG_PAGES*PAGE_SIZE;
1.1 root 444: p = (unsigned long) create_tables((char *)p,argc,envc);
445: current->brk = ex.a_bss +
446: (current->end_data = ex.a_data +
447: (current->end_code = ex.a_text));
1.1.1.5 root 448: current->start_stack = p;
1.1.1.6 root 449: current->rss = (LIBRARY_OFFSET - p + PAGE_SIZE-1) / PAGE_SIZE;
1.1.1.4 root 450: current->suid = current->euid = e_uid;
451: current->sgid = current->egid = e_gid;
1.1.1.7 ! root 452: if (N_MAGIC(ex) == OMAGIC)
! 453: read_omagic(inode, ex.a_text+ex.a_data);
1.1 root 454: eip[0] = ex.a_entry; /* eip, magic happens :-) */
455: eip[3] = p; /* stack pointer */
1.1.1.5 root 456: if (current->flags & PF_PTRACED)
457: send_sig(SIGTRAP, current, 0);
1.1 root 458: return 0;
1.1.1.2 root 459: exec_error2:
460: iput(inode);
461: exec_error1:
462: for (i=0 ; i<MAX_ARG_PAGES ; i++)
463: free_page(page[i]);
464: return(retval);
1.1 root 465: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.