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