This source file includes following definitions.
- register_binfmt
- unregister_binfmt
- open_inode
- aout_core_dump
- sys_uselib
- create_tables
- count
- copy_strings
- change_ldt
- read_exec
- flush_old_exec
- do_execve
- sys_execve
- set_brk
- load_aout_binary
- load_aout_library
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <linux/fs.h>
27 #include <linux/sched.h>
28 #include <linux/kernel.h>
29 #include <linux/mm.h>
30 #include <linux/mman.h>
31 #include <linux/a.out.h>
32 #include <linux/errno.h>
33 #include <linux/signal.h>
34 #include <linux/string.h>
35 #include <linux/stat.h>
36 #include <linux/fcntl.h>
37 #include <linux/ptrace.h>
38 #include <linux/user.h>
39 #include <linux/segment.h>
40 #include <linux/malloc.h>
41
42 #include <asm/system.h>
43
44 #include <linux/binfmts.h>
45 #include <linux/personality.h>
46
47 #include <asm/segment.h>
48 #include <asm/system.h>
49
50 asmlinkage int sys_exit(int exit_code);
51 asmlinkage int sys_brk(unsigned long);
52
53 extern void shm_exit (void);
54
55 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
56 static int load_aout_library(int fd);
57 static int aout_core_dump(long signr, struct pt_regs * regs);
58
59
60
61
62
63 static struct linux_binfmt aout_format = {
64 NULL, NULL, load_aout_binary, load_aout_library, aout_core_dump
65 };
66 static struct linux_binfmt *formats = &aout_format;
67
68 int register_binfmt(struct linux_binfmt * fmt)
69 {
70 struct linux_binfmt ** tmp = &formats;
71
72 if (!fmt)
73 return -EINVAL;
74 if (fmt->next)
75 return -EBUSY;
76 while (*tmp) {
77 if (fmt == *tmp)
78 return -EBUSY;
79 tmp = &(*tmp)->next;
80 }
81 *tmp = fmt;
82 return 0;
83 }
84
85 int unregister_binfmt(struct linux_binfmt * fmt)
86 {
87 struct linux_binfmt ** tmp = &formats;
88
89 while (*tmp) {
90 if (fmt == *tmp) {
91 *tmp = fmt->next;
92 return 0;
93 }
94 tmp = &(*tmp)->next;
95 }
96 return -EINVAL;
97 }
98
99 int open_inode(struct inode * inode, int mode)
100 {
101 int error, fd;
102 struct file *f, **fpp;
103
104 if (!inode->i_op || !inode->i_op->default_file_ops)
105 return -EINVAL;
106 f = get_empty_filp();
107 if (!f)
108 return -EMFILE;
109 fd = 0;
110 fpp = current->files->fd;
111 for (;;) {
112 if (!*fpp)
113 break;
114 if (++fd > NR_OPEN)
115 return -ENFILE;
116 fpp++;
117 }
118 *fpp = f;
119 f->f_flags = mode;
120 f->f_mode = (mode+1) & O_ACCMODE;
121 f->f_inode = inode;
122 f->f_pos = 0;
123 f->f_reada = 0;
124 f->f_op = inode->i_op->default_file_ops;
125 if (f->f_op->open) {
126 error = f->f_op->open(inode,f);
127 if (error) {
128 *fpp = NULL;
129 f->f_count--;
130 return error;
131 }
132 }
133 inode->i_count++;
134 return fd;
135 }
136
137
138
139
140
141 #define DUMP_WRITE(addr,nr) \
142 while (file.f_op->write(inode,&file,(char *)(addr),(nr)) != (nr)) goto close_coredump
143
144 #define DUMP_SEEK(offset) \
145 if (file.f_op->lseek) { \
146 if (file.f_op->lseek(inode,&file,(offset),0) != (offset)) \
147 goto close_coredump; \
148 } else file.f_pos = (offset)
149
150
151
152
153
154
155
156
157
158
159 static int aout_core_dump(long signr, struct pt_regs * regs)
160 {
161 struct inode * inode = NULL;
162 struct file file;
163 unsigned short fs;
164 int has_dumped = 0;
165 char corefile[6+sizeof(current->comm)];
166 int i;
167 register int dump_start, dump_size;
168 struct user dump;
169
170 if (!current->dumpable)
171 return 0;
172 current->dumpable = 0;
173
174
175 if (current->rlim[RLIMIT_CORE].rlim_cur < PAGE_SIZE)
176 return 0;
177 fs = get_fs();
178 set_fs(KERNEL_DS);
179 memcpy(corefile,"core.",5);
180 #if 0
181 memcpy(corefile+5,current->comm,sizeof(current->comm));
182 #else
183 corefile[4] = '\0';
184 #endif
185 if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) {
186 inode = NULL;
187 goto end_coredump;
188 }
189 if (!S_ISREG(inode->i_mode))
190 goto end_coredump;
191 if (!inode->i_op || !inode->i_op->default_file_ops)
192 goto end_coredump;
193 file.f_mode = 3;
194 file.f_flags = 0;
195 file.f_count = 1;
196 file.f_inode = inode;
197 file.f_pos = 0;
198 file.f_reada = 0;
199 file.f_op = inode->i_op->default_file_ops;
200 if (file.f_op->open)
201 if (file.f_op->open(inode,&file))
202 goto end_coredump;
203 if (!file.f_op->write)
204 goto close_coredump;
205 has_dumped = 1;
206
207 dump.magic = CMAGIC;
208 dump.start_code = 0;
209 dump.start_stack = regs->esp & ~(PAGE_SIZE - 1);
210 dump.u_tsize = ((unsigned long) current->mm->end_code) >> 12;
211 dump.u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> 12;
212 dump.u_dsize -= dump.u_tsize;
213 dump.u_ssize = 0;
214 for(i=0; i<8; i++) dump.u_debugreg[i] = current->debugreg[i];
215 if (dump.start_stack < TASK_SIZE)
216 dump.u_ssize = ((unsigned long) (TASK_SIZE - dump.start_stack)) >> 12;
217
218
219 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
220 current->rlim[RLIMIT_CORE].rlim_cur)
221 dump.u_dsize = 0;
222
223 if ((dump.u_ssize+1) * PAGE_SIZE >
224 current->rlim[RLIMIT_CORE].rlim_cur)
225 dump.u_ssize = 0;
226 strncpy(dump.u_comm, current->comm, sizeof(current->comm));
227 dump.u_ar0 = (struct pt_regs *)(((int)(&dump.regs)) -((int)(&dump)));
228 dump.signal = signr;
229 dump.regs = *regs;
230
231
232 if (hard_math) {
233 if ((dump.u_fpvalid = current->used_math) != 0) {
234 if (last_task_used_math == current)
235 __asm__("clts ; fnsave %0": :"m" (dump.i387));
236 else
237 memcpy(&dump.i387,¤t->tss.i387.hard,sizeof(dump.i387));
238 }
239 } else {
240
241
242 dump.u_fpvalid = 0;
243 }
244 set_fs(KERNEL_DS);
245
246 DUMP_WRITE(&dump,sizeof(dump));
247
248 DUMP_SEEK(PAGE_SIZE);
249
250 set_fs(USER_DS);
251
252 if (dump.u_dsize != 0) {
253 dump_start = dump.u_tsize << 12;
254 dump_size = dump.u_dsize << 12;
255 DUMP_WRITE(dump_start,dump_size);
256 }
257
258 if (dump.u_ssize != 0) {
259 dump_start = dump.start_stack;
260 dump_size = dump.u_ssize << 12;
261 DUMP_WRITE(dump_start,dump_size);
262 }
263
264 set_fs(KERNEL_DS);
265 DUMP_WRITE(current,sizeof(*current));
266 close_coredump:
267 if (file.f_op->release)
268 file.f_op->release(inode,&file);
269 end_coredump:
270 set_fs(fs);
271 iput(inode);
272 return has_dumped;
273 }
274
275
276
277
278
279
280
281 asmlinkage int sys_uselib(const char * library)
282 {
283 int fd, retval;
284 struct file * file;
285 struct linux_binfmt * fmt;
286
287 fd = sys_open(library, 0, 0);
288 if (fd < 0)
289 return fd;
290 file = current->files->fd[fd];
291 retval = -ENOEXEC;
292 if (file && file->f_inode && file->f_op && file->f_op->read) {
293 for (fmt = formats ; fmt ; fmt = fmt->next) {
294 int (*fn)(int) = fmt->load_shlib;
295 if (!fn)
296 break;
297 retval = fn(fd);
298 if (retval != -ENOEXEC)
299 break;
300 }
301 }
302 sys_close(fd);
303 return retval;
304 }
305
306
307
308
309
310
311 unsigned long * create_tables(char * p,int argc,int envc,int ibcs)
312 {
313 unsigned long *argv,*envp;
314 unsigned long * sp;
315 struct vm_area_struct *mpnt;
316
317 mpnt = (struct vm_area_struct *)kmalloc(sizeof(*mpnt), GFP_KERNEL);
318 if (mpnt) {
319 mpnt->vm_task = current;
320 mpnt->vm_start = PAGE_MASK & (unsigned long) p;
321 mpnt->vm_end = TASK_SIZE;
322 mpnt->vm_page_prot = PAGE_PRIVATE|PAGE_DIRTY;
323 mpnt->vm_flags = VM_STACK_FLAGS;
324 mpnt->vm_share = NULL;
325 mpnt->vm_ops = NULL;
326 mpnt->vm_offset = 0;
327 mpnt->vm_inode = NULL;
328 mpnt->vm_pte = 0;
329 insert_vm_struct(current, mpnt);
330 }
331 sp = (unsigned long *) (0xfffffffc & (unsigned long) p);
332 sp -= envc+1;
333 envp = sp;
334 sp -= argc+1;
335 argv = sp;
336 if (!ibcs) {
337 put_fs_long((unsigned long)envp,--sp);
338 put_fs_long((unsigned long)argv,--sp);
339 }
340 put_fs_long((unsigned long)argc,--sp);
341 current->mm->arg_start = (unsigned long) p;
342 while (argc-->0) {
343 put_fs_long((unsigned long) p,argv++);
344 while (get_fs_byte(p++)) ;
345 }
346 put_fs_long(0,argv);
347 current->mm->arg_end = current->mm->env_start = (unsigned long) p;
348 while (envc-->0) {
349 put_fs_long((unsigned long) p,envp++);
350 while (get_fs_byte(p++)) ;
351 }
352 put_fs_long(0,envp);
353 current->mm->env_end = (unsigned long) p;
354 return sp;
355 }
356
357
358
359
360 static int count(char ** argv)
361 {
362 int i=0;
363 char ** tmp;
364
365 if ((tmp = argv) != 0)
366 while (get_fs_long((unsigned long *) (tmp++)))
367 i++;
368
369 return i;
370 }
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389 unsigned long copy_strings(int argc,char ** argv,unsigned long *page,
390 unsigned long p, int from_kmem)
391 {
392 char *tmp, *pag = NULL;
393 int len, offset = 0;
394 unsigned long old_fs, new_fs;
395
396 if (!p)
397 return 0;
398 new_fs = get_ds();
399 old_fs = get_fs();
400 if (from_kmem==2)
401 set_fs(new_fs);
402 while (argc-- > 0) {
403 if (from_kmem == 1)
404 set_fs(new_fs);
405 if (!(tmp = (char *)get_fs_long(((unsigned long *)argv)+argc)))
406 panic("VFS: argc is wrong");
407 if (from_kmem == 1)
408 set_fs(old_fs);
409 len=0;
410 do {
411 len++;
412 } while (get_fs_byte(tmp++));
413 if (p < len) {
414 set_fs(old_fs);
415 return 0;
416 }
417 while (len) {
418 --p; --tmp; --len;
419 if (--offset < 0) {
420 offset = p % PAGE_SIZE;
421 if (from_kmem==2)
422 set_fs(old_fs);
423 if (!(pag = (char *) page[p/PAGE_SIZE]) &&
424 !(pag = (char *) page[p/PAGE_SIZE] =
425 (unsigned long *) get_free_page(GFP_USER)))
426 return 0;
427 if (from_kmem==2)
428 set_fs(new_fs);
429
430 }
431 *(pag + offset) = get_fs_byte(tmp);
432 }
433 }
434 if (from_kmem==2)
435 set_fs(old_fs);
436 return p;
437 }
438
439 unsigned long change_ldt(unsigned long text_size,unsigned long * page)
440 {
441 unsigned long code_limit,data_limit,code_base,data_base;
442 int i;
443
444 code_limit = TASK_SIZE;
445 data_limit = TASK_SIZE;
446 code_base = data_base = 0;
447 current->mm->start_code = code_base;
448 data_base += data_limit;
449 for (i=MAX_ARG_PAGES-1 ; i>=0 ; i--) {
450 data_base -= PAGE_SIZE;
451 if (page[i]) {
452 current->mm->rss++;
453 put_dirty_page(current,page[i],data_base);
454 }
455 }
456 return data_limit;
457 }
458
459
460
461
462
463
464 int read_exec(struct inode *inode, unsigned long offset,
465 char * addr, unsigned long count)
466 {
467 struct file file;
468 int result = -ENOEXEC;
469
470 if (!inode->i_op || !inode->i_op->default_file_ops)
471 goto end_readexec;
472 file.f_mode = 1;
473 file.f_flags = 0;
474 file.f_count = 1;
475 file.f_inode = inode;
476 file.f_pos = 0;
477 file.f_reada = 0;
478 file.f_op = inode->i_op->default_file_ops;
479 if (file.f_op->open)
480 if (file.f_op->open(inode,&file))
481 goto end_readexec;
482 if (!file.f_op || !file.f_op->read)
483 goto close_readexec;
484 if (file.f_op->lseek) {
485 if (file.f_op->lseek(inode,&file,offset,0) != offset)
486 goto close_readexec;
487 } else
488 file.f_pos = offset;
489 if (get_fs() == USER_DS) {
490 result = verify_area(VERIFY_WRITE, addr, count);
491 if (result)
492 goto close_readexec;
493 }
494 result = file.f_op->read(inode, &file, addr, count);
495 close_readexec:
496 if (file.f_op->release)
497 file.f_op->release(inode,&file);
498 end_readexec:
499 return result;
500 }
501
502
503
504
505
506
507
508 void flush_old_exec(struct linux_binprm * bprm)
509 {
510 int i;
511 int ch;
512 char * name;
513 struct vm_area_struct * mpnt, *mpnt1;
514
515 current->dumpable = 1;
516 name = bprm->filename;
517 for (i=0; (ch = *(name++)) != '\0';) {
518 if (ch == '/')
519 i = 0;
520 else
521 if (i < 15)
522 current->comm[i++] = ch;
523 }
524 current->comm[i] = '\0';
525 if (current->shm)
526 shm_exit();
527
528
529 mpnt = current->mm->mmap;
530 current->mm->mmap = NULL;
531 while (mpnt) {
532 mpnt1 = mpnt->vm_next;
533 if (mpnt->vm_ops && mpnt->vm_ops->close)
534 mpnt->vm_ops->close(mpnt);
535 if (mpnt->vm_inode)
536 iput(mpnt->vm_inode);
537 kfree(mpnt);
538 mpnt = mpnt1;
539 }
540
541
542 if (current->ldt) {
543 free_page((unsigned long) current->ldt);
544 current->ldt = NULL;
545 for (i=1 ; i<NR_TASKS ; i++) {
546 if (task[i] == current) {
547 set_ldt_desc(gdt+(i<<1)+
548 FIRST_LDT_ENTRY,&default_ldt, 1);
549 load_ldt(i);
550 }
551 }
552 }
553
554 for (i=0 ; i<8 ; i++) current->debugreg[i] = 0;
555
556 if (bprm->e_uid != current->euid || bprm->e_gid != current->egid ||
557 !permission(bprm->inode,MAY_READ))
558 current->dumpable = 0;
559 current->signal = 0;
560 for (i=0 ; i<32 ; i++) {
561 current->sigaction[i].sa_mask = 0;
562 current->sigaction[i].sa_flags = 0;
563 if (current->sigaction[i].sa_handler != SIG_IGN)
564 current->sigaction[i].sa_handler = NULL;
565 }
566 for (i=0 ; i<NR_OPEN ; i++)
567 if (FD_ISSET(i,¤t->files->close_on_exec))
568 sys_close(i);
569 FD_ZERO(¤t->files->close_on_exec);
570 clear_page_tables(current);
571 if (last_task_used_math == current)
572 last_task_used_math = NULL;
573 current->used_math = 0;
574 }
575
576
577
578
579 int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
580 {
581 struct linux_binprm bprm;
582 struct linux_binfmt * fmt;
583 unsigned long old_fs;
584 int i;
585 int retval;
586 int sh_bang = 0;
587
588 if (regs->cs != USER_CS)
589 return -EINVAL;
590 bprm.p = PAGE_SIZE*MAX_ARG_PAGES-4;
591 for (i=0 ; i<MAX_ARG_PAGES ; i++)
592 bprm.page[i] = 0;
593 retval = open_namei(filename, 0, 0, &bprm.inode, NULL);
594 if (retval)
595 return retval;
596 bprm.filename = filename;
597 bprm.argc = count(argv);
598 bprm.envc = count(envp);
599
600 restart_interp:
601 if (!S_ISREG(bprm.inode->i_mode)) {
602 retval = -EACCES;
603 goto exec_error2;
604 }
605 if (IS_NOEXEC(bprm.inode)) {
606 retval = -EPERM;
607 goto exec_error2;
608 }
609 if (!bprm.inode->i_sb) {
610 retval = -EACCES;
611 goto exec_error2;
612 }
613 i = bprm.inode->i_mode;
614 if (IS_NOSUID(bprm.inode) && (((i & S_ISUID) && bprm.inode->i_uid != current->
615 euid) || ((i & S_ISGID) && !in_group_p(bprm.inode->i_gid))) && !suser()) {
616 retval = -EPERM;
617 goto exec_error2;
618 }
619
620 if (current->flags & PF_PTRACED) {
621 bprm.e_uid = current->euid;
622 bprm.e_gid = current->egid;
623 } else {
624 bprm.e_uid = (i & S_ISUID) ? bprm.inode->i_uid : current->euid;
625 bprm.e_gid = (i & S_ISGID) ? bprm.inode->i_gid : current->egid;
626 }
627 if (current->euid == bprm.inode->i_uid)
628 i >>= 6;
629 else if (in_group_p(bprm.inode->i_gid))
630 i >>= 3;
631 if (!(i & 1) &&
632 !((bprm.inode->i_mode & 0111) && suser())) {
633 retval = -EACCES;
634 goto exec_error2;
635 }
636 memset(bprm.buf,0,sizeof(bprm.buf));
637 old_fs = get_fs();
638 set_fs(get_ds());
639 retval = read_exec(bprm.inode,0,bprm.buf,128);
640 set_fs(old_fs);
641 if (retval < 0)
642 goto exec_error2;
643 if ((bprm.buf[0] == '#') && (bprm.buf[1] == '!') && (!sh_bang)) {
644
645
646
647
648
649 char *cp, *interp, *i_name, *i_arg;
650
651 iput(bprm.inode);
652 bprm.buf[127] = '\0';
653 if ((cp = strchr(bprm.buf, '\n')) == NULL)
654 cp = bprm.buf+127;
655 *cp = '\0';
656 while (cp > bprm.buf) {
657 cp--;
658 if ((*cp == ' ') || (*cp == '\t'))
659 *cp = '\0';
660 else
661 break;
662 }
663 for (cp = bprm.buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
664 if (!cp || *cp == '\0') {
665 retval = -ENOEXEC;
666 goto exec_error1;
667 }
668 interp = i_name = cp;
669 i_arg = 0;
670 for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++) {
671 if (*cp == '/')
672 i_name = cp+1;
673 }
674 while ((*cp == ' ') || (*cp == '\t'))
675 *cp++ = '\0';
676 if (*cp)
677 i_arg = cp;
678
679
680
681
682 if (sh_bang++ == 0) {
683 bprm.p = copy_strings(bprm.envc, envp, bprm.page, bprm.p, 0);
684 bprm.p = copy_strings(--bprm.argc, argv+1, bprm.page, bprm.p, 0);
685 }
686
687
688
689
690
691
692
693
694 bprm.p = copy_strings(1, &bprm.filename, bprm.page, bprm.p, 2);
695 bprm.argc++;
696 if (i_arg) {
697 bprm.p = copy_strings(1, &i_arg, bprm.page, bprm.p, 2);
698 bprm.argc++;
699 }
700 bprm.p = copy_strings(1, &i_name, bprm.page, bprm.p, 2);
701 bprm.argc++;
702 if (!bprm.p) {
703 retval = -E2BIG;
704 goto exec_error1;
705 }
706
707
708
709
710
711 retval = open_namei(interp, 0, 0, &bprm.inode, NULL);
712 if (retval)
713 goto exec_error1;
714 goto restart_interp;
715 }
716 if (!sh_bang) {
717 bprm.p = copy_strings(bprm.envc,envp,bprm.page,bprm.p,0);
718 bprm.p = copy_strings(bprm.argc,argv,bprm.page,bprm.p,0);
719 if (!bprm.p) {
720 retval = -E2BIG;
721 goto exec_error2;
722 }
723 }
724
725 bprm.sh_bang = sh_bang;
726 for (fmt = formats ; fmt ; fmt = fmt->next) {
727 int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
728 if (!fn)
729 break;
730 retval = fn(&bprm, regs);
731 if (retval >= 0) {
732 iput(bprm.inode);
733 current->did_exec = 1;
734 return retval;
735 }
736 if (retval != -ENOEXEC)
737 break;
738 }
739 exec_error2:
740 iput(bprm.inode);
741 exec_error1:
742 for (i=0 ; i<MAX_ARG_PAGES ; i++)
743 free_page(bprm.page[i]);
744 return(retval);
745 }
746
747
748
749
750 asmlinkage int sys_execve(struct pt_regs regs)
751 {
752 int error;
753 char * filename;
754
755 error = getname((char *) regs.ebx, &filename);
756 if (error)
757 return error;
758 error = do_execve(filename, (char **) regs.ecx, (char **) regs.edx, ®s);
759 putname(filename);
760 return error;
761 }
762
763 static void set_brk(unsigned long start, unsigned long end)
764 {
765 start = PAGE_ALIGN(start);
766 end = PAGE_ALIGN(end);
767 if (end <= start)
768 return;
769 do_mmap(NULL, start, end - start,
770 PROT_READ | PROT_WRITE | PROT_EXEC,
771 MAP_FIXED | MAP_PRIVATE, 0);
772 }
773
774
775
776
777
778
779 static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
780 {
781 struct exec ex;
782 struct file * file;
783 int fd, error;
784 unsigned long p = bprm->p;
785 unsigned long fd_offset;
786
787 ex = *((struct exec *) bprm->buf);
788 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC &&
789 N_MAGIC(ex) != QMAGIC) ||
790 ex.a_trsize || ex.a_drsize ||
791 bprm->inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
792 return -ENOEXEC;
793 }
794
795 current->personality = PER_LINUX;
796 fd_offset = N_TXTOFF(ex);
797 if (N_MAGIC(ex) == ZMAGIC && fd_offset != BLOCK_SIZE) {
798 printk(KERN_NOTICE "N_TXTOFF != BLOCK_SIZE. See a.out.h.\n");
799 return -ENOEXEC;
800 }
801
802 if (N_MAGIC(ex) == ZMAGIC && ex.a_text &&
803 (fd_offset < bprm->inode->i_sb->s_blocksize)) {
804 printk(KERN_NOTICE "N_TXTOFF < BLOCK_SIZE. Please convert binary.\n");
805 return -ENOEXEC;
806 }
807
808
809 flush_old_exec(bprm);
810
811 current->mm->brk = ex.a_bss +
812 (current->mm->start_brk =
813 (current->mm->end_data = ex.a_data +
814 (current->mm->end_code = ex.a_text +
815 (current->mm->start_code = N_TXTADDR(ex)))));
816 current->mm->rss = 0;
817 current->mm->mmap = NULL;
818 current->suid = current->euid = current->fsuid = bprm->e_uid;
819 current->sgid = current->egid = current->fsgid = bprm->e_gid;
820 if (N_MAGIC(ex) == OMAGIC) {
821 do_mmap(NULL, 0, ex.a_text+ex.a_data,
822 PROT_READ|PROT_WRITE|PROT_EXEC,
823 MAP_FIXED|MAP_PRIVATE, 0);
824 read_exec(bprm->inode, 32, (char *) 0, ex.a_text+ex.a_data);
825 } else {
826 if (ex.a_text & 0xfff || ex.a_data & 0xfff)
827 printk(KERN_NOTICE "executable not page aligned\n");
828
829 fd = open_inode(bprm->inode, O_RDONLY);
830
831 if (fd < 0)
832 return fd;
833 file = current->files->fd[fd];
834 if (!file->f_op || !file->f_op->mmap) {
835 sys_close(fd);
836 do_mmap(NULL, 0, ex.a_text+ex.a_data,
837 PROT_READ|PROT_WRITE|PROT_EXEC,
838 MAP_FIXED|MAP_PRIVATE, 0);
839 read_exec(bprm->inode, fd_offset,
840 (char *) N_TXTADDR(ex), ex.a_text+ex.a_data);
841 goto beyond_if;
842 }
843
844 if (ex.a_text) {
845 error = do_mmap(file, N_TXTADDR(ex), ex.a_text,
846 PROT_READ | PROT_EXEC,
847 MAP_FIXED | MAP_SHARED | MAP_DENYWRITE | MAP_EXECUTABLE,
848 fd_offset);
849
850 if (error != N_TXTADDR(ex)) {
851 sys_close(fd);
852 send_sig(SIGSEGV, current, 0);
853 return -EINVAL;
854 }
855 }
856
857 error = do_mmap(file, N_TXTADDR(ex) + ex.a_text, ex.a_data,
858 PROT_READ | PROT_WRITE | PROT_EXEC,
859 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
860 fd_offset + ex.a_text);
861 sys_close(fd);
862 if (error != N_TXTADDR(ex) + ex.a_text) {
863 send_sig(SIGSEGV, current, 0);
864 return -EINVAL;
865 }
866 }
867 beyond_if:
868 if (current->exec_domain && current->exec_domain->use_count)
869 (*current->exec_domain->use_count)--;
870 if (current->binfmt && current->binfmt->use_count)
871 (*current->binfmt->use_count)--;
872 current->exec_domain = lookup_exec_domain(current->personality);
873 current->binfmt = &aout_format;
874 if (current->exec_domain && current->exec_domain->use_count)
875 (*current->exec_domain->use_count)++;
876 if (current->binfmt && current->binfmt->use_count)
877 (*current->binfmt->use_count)++;
878
879 set_brk(current->mm->start_brk, current->mm->brk);
880
881 p += change_ldt(ex.a_text,bprm->page);
882 p -= MAX_ARG_PAGES*PAGE_SIZE;
883 p = (unsigned long)create_tables((char *)p,
884 bprm->argc, bprm->envc,
885 current->personality != PER_LINUX);
886 current->mm->start_stack = p;
887 regs->eip = ex.a_entry;
888 regs->esp = p;
889 if (current->flags & PF_PTRACED)
890 send_sig(SIGTRAP, current, 0);
891 return 0;
892 }
893
894
895 static int load_aout_library(int fd)
896 {
897 struct file * file;
898 struct exec ex;
899 struct inode * inode;
900 unsigned int len;
901 unsigned int bss;
902 unsigned int start_addr;
903 int error;
904
905 file = current->files->fd[fd];
906 inode = file->f_inode;
907
908 set_fs(KERNEL_DS);
909 if (file->f_op->read(inode, file, (char *) &ex, sizeof(ex)) != sizeof(ex)) {
910 return -EACCES;
911 }
912 set_fs(USER_DS);
913
914
915 if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != QMAGIC) || ex.a_trsize ||
916 ex.a_drsize || ((ex.a_entry & 0xfff) && N_MAGIC(ex) == ZMAGIC) ||
917 inode->i_size < ex.a_text+ex.a_data+ex.a_syms+N_TXTOFF(ex)) {
918 return -ENOEXEC;
919 }
920 if (N_MAGIC(ex) == ZMAGIC && N_TXTOFF(ex) &&
921 (N_TXTOFF(ex) < inode->i_sb->s_blocksize)) {
922 printk("N_TXTOFF < BLOCK_SIZE. Please convert library\n");
923 return -ENOEXEC;
924 }
925
926 if (N_FLAGS(ex)) return -ENOEXEC;
927
928
929
930
931 start_addr = ex.a_entry & 0xfffff000;
932
933
934 error = do_mmap(file, start_addr, ex.a_text + ex.a_data,
935 PROT_READ | PROT_WRITE | PROT_EXEC,
936 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
937 N_TXTOFF(ex));
938 if (error != start_addr)
939 return error;
940 len = PAGE_ALIGN(ex.a_text + ex.a_data);
941 bss = ex.a_text + ex.a_data + ex.a_bss;
942 if (bss > len)
943 do_mmap(NULL, start_addr + len, bss-len,
944 PROT_READ|PROT_WRITE|PROT_EXEC,
945 MAP_PRIVATE|MAP_FIXED, 0);
946 return 0;
947 }