aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c173
1 files changed, 21 insertions, 152 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index a93b1170551b..41a958a7585e 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -134,8 +134,7 @@ static int padzero(unsigned long elf_bss)
134 134
135static int 135static int
136create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, 136create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
137 int interp_aout, unsigned long load_addr, 137 unsigned long load_addr, unsigned long interp_load_addr)
138 unsigned long interp_load_addr)
139{ 138{
140 unsigned long p = bprm->p; 139 unsigned long p = bprm->p;
141 int argc = bprm->argc; 140 int argc = bprm->argc;
@@ -223,12 +222,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
223 222
224 sp = STACK_ADD(p, ei_index); 223 sp = STACK_ADD(p, ei_index);
225 224
226 items = (argc + 1) + (envc + 1); 225 items = (argc + 1) + (envc + 1) + 1;
227 if (interp_aout) {
228 items += 3; /* a.out interpreters require argv & envp too */
229 } else {
230 items += 1; /* ELF interpreters only put argc on the stack */
231 }
232 bprm->p = STACK_ROUND(sp, items); 226 bprm->p = STACK_ROUND(sp, items);
233 227
234 /* Point sp at the lowest address on the stack */ 228 /* Point sp at the lowest address on the stack */
@@ -251,16 +245,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
251 /* Now, let's put argc (and argv, envp if appropriate) on the stack */ 245 /* Now, let's put argc (and argv, envp if appropriate) on the stack */
252 if (__put_user(argc, sp++)) 246 if (__put_user(argc, sp++))
253 return -EFAULT; 247 return -EFAULT;
254 if (interp_aout) { 248 argv = sp;
255 argv = sp + 2; 249 envp = argv + argc + 1;
256 envp = argv + argc + 1;
257 if (__put_user((elf_addr_t)(unsigned long)argv, sp++) ||
258 __put_user((elf_addr_t)(unsigned long)envp, sp++))
259 return -EFAULT;
260 } else {
261 argv = sp;
262 envp = argv + argc + 1;
263 }
264 250
265 /* Populate argv and envp */ 251 /* Populate argv and envp */
266 p = current->mm->arg_end = current->mm->arg_start; 252 p = current->mm->arg_end = current->mm->arg_start;
@@ -513,61 +499,6 @@ out:
513 return error; 499 return error;
514} 500}
515 501
516#ifdef CONFIG_ARCH_SUPPORTS_AOUT
517static unsigned long load_aout_interp(struct exec *interp_ex,
518 struct file *interpreter)
519{
520 unsigned long text_data, elf_entry = ~0UL;
521 char __user * addr;
522 loff_t offset;
523
524 current->mm->end_code = interp_ex->a_text;
525 text_data = interp_ex->a_text + interp_ex->a_data;
526 current->mm->end_data = text_data;
527 current->mm->brk = interp_ex->a_bss + text_data;
528
529 switch (N_MAGIC(*interp_ex)) {
530 case OMAGIC:
531 offset = 32;
532 addr = (char __user *)0;
533 break;
534 case ZMAGIC:
535 case QMAGIC:
536 offset = N_TXTOFF(*interp_ex);
537 addr = (char __user *)N_TXTADDR(*interp_ex);
538 break;
539 default:
540 goto out;
541 }
542
543 down_write(&current->mm->mmap_sem);
544 do_brk(0, text_data);
545 up_write(&current->mm->mmap_sem);
546 if (!interpreter->f_op || !interpreter->f_op->read)
547 goto out;
548 if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
549 goto out;
550 flush_icache_range((unsigned long)addr,
551 (unsigned long)addr + text_data);
552
553 down_write(&current->mm->mmap_sem);
554 do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
555 interp_ex->a_bss);
556 up_write(&current->mm->mmap_sem);
557 elf_entry = interp_ex->a_entry;
558
559out:
560 return elf_entry;
561}
562#else
563/* dummy extern - the function should never be called if !CONFIG_AOUT_BINFMT */
564static inline unsigned long load_aout_interp(struct exec *interp_ex,
565 struct file *interpreter)
566{
567 return -ELIBACC;
568}
569#endif
570
571/* 502/*
572 * These are the functions used to load ELF style executables and shared 503 * These are the functions used to load ELF style executables and shared
573 * libraries. There is no binary dependent code anywhere else. 504 * libraries. There is no binary dependent code anywhere else.
@@ -576,13 +507,6 @@ static inline unsigned long load_aout_interp(struct exec *interp_ex,
576#define INTERPRETER_NONE 0 507#define INTERPRETER_NONE 0
577#define INTERPRETER_ELF 2 508#define INTERPRETER_ELF 2
578 509
579#ifdef CONFIG_ARCH_SUPPORTS_AOUT
580#define INTERPRETER_AOUT 1
581#define IS_AOUT_INTERP(x) ((x) == INTERPRETER_AOUT)
582#else
583#define IS_AOUT_INTERP(x) (0)
584#endif
585
586#ifndef STACK_RND_MASK 510#ifndef STACK_RND_MASK
587#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */ 511#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */
588#endif 512#endif
@@ -609,7 +533,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
609 unsigned long load_addr = 0, load_bias = 0; 533 unsigned long load_addr = 0, load_bias = 0;
610 int load_addr_set = 0; 534 int load_addr_set = 0;
611 char * elf_interpreter = NULL; 535 char * elf_interpreter = NULL;
612 unsigned int interpreter_type = INTERPRETER_NONE;
613 unsigned long error; 536 unsigned long error;
614 struct elf_phdr *elf_ppnt, *elf_phdata; 537 struct elf_phdr *elf_ppnt, *elf_phdata;
615 unsigned long elf_bss, elf_brk; 538 unsigned long elf_bss, elf_brk;
@@ -620,7 +543,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
620 unsigned long interp_load_addr = 0; 543 unsigned long interp_load_addr = 0;
621 unsigned long start_code, end_code, start_data, end_data; 544 unsigned long start_code, end_code, start_data, end_data;
622 unsigned long reloc_func_desc = 0; 545 unsigned long reloc_func_desc = 0;
623 char passed_fileno[6];
624 struct files_struct *files; 546 struct files_struct *files;
625 int executable_stack = EXSTACK_DEFAULT; 547 int executable_stack = EXSTACK_DEFAULT;
626 unsigned long def_flags = 0; 548 unsigned long def_flags = 0;
@@ -789,62 +711,18 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
789 711
790 /* Some simple consistency checks for the interpreter */ 712 /* Some simple consistency checks for the interpreter */
791 if (elf_interpreter) { 713 if (elf_interpreter) {
792 static int warn;
793#ifdef CONFIG_ARCH_SUPPORTS_AOUT
794 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
795
796 /* Now figure out which format our binary is */
797 if ((N_MAGIC(loc->interp_ex) != OMAGIC) &&
798 (N_MAGIC(loc->interp_ex) != ZMAGIC) &&
799 (N_MAGIC(loc->interp_ex) != QMAGIC))
800 interpreter_type = INTERPRETER_ELF;
801#else
802 interpreter_type = INTERPRETER_ELF;
803#endif
804 if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
805 interpreter_type &= ~INTERPRETER_ELF;
806
807 if (IS_AOUT_INTERP(interpreter_type) && warn < 10) {
808 printk(KERN_WARNING "a.out ELF interpreter %s is "
809 "deprecated and will not be supported "
810 "after Linux 2.6.25\n", elf_interpreter);
811 warn++;
812 }
813
814 retval = -ELIBBAD; 714 retval = -ELIBBAD;
815 if (!interpreter_type) 715 /* Not an ELF interpreter */
716 if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
816 goto out_free_dentry; 717 goto out_free_dentry;
817
818 /* Make sure only one type was selected */
819 if ((interpreter_type & INTERPRETER_ELF) &&
820 interpreter_type != INTERPRETER_ELF) {
821 // FIXME - ratelimit this before re-enabling
822 // printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
823 interpreter_type = INTERPRETER_ELF;
824 }
825 /* Verify the interpreter has a valid arch */ 718 /* Verify the interpreter has a valid arch */
826 if ((interpreter_type == INTERPRETER_ELF) && 719 if (!elf_check_arch(&loc->interp_elf_ex))
827 !elf_check_arch(&loc->interp_elf_ex))
828 goto out_free_dentry; 720 goto out_free_dentry;
829 } else { 721 } else {
830 /* Executables without an interpreter also need a personality */ 722 /* Executables without an interpreter also need a personality */
831 SET_PERSONALITY(loc->elf_ex, 0); 723 SET_PERSONALITY(loc->elf_ex, 0);
832 } 724 }
833 725
834 /* OK, we are done with that, now set up the arg stuff,
835 and then start this sucker up */
836 if (IS_AOUT_INTERP(interpreter_type) && !bprm->sh_bang) {
837 char *passed_p = passed_fileno;
838 sprintf(passed_fileno, "%d", elf_exec_fileno);
839
840 if (elf_interpreter) {
841 retval = copy_strings_kernel(1, &passed_p, bprm);
842 if (retval)
843 goto out_free_dentry;
844 bprm->argc++;
845 }
846 }
847
848 /* Flush all traces of the currently running executable */ 726 /* Flush all traces of the currently running executable */
849 retval = flush_old_exec(bprm); 727 retval = flush_old_exec(bprm);
850 if (retval) 728 if (retval)
@@ -1022,24 +900,19 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1022 } 900 }
1023 901
1024 if (elf_interpreter) { 902 if (elf_interpreter) {
1025 if (IS_AOUT_INTERP(interpreter_type)) { 903 unsigned long uninitialized_var(interp_map_addr);
1026 elf_entry = load_aout_interp(&loc->interp_ex, 904
1027 interpreter); 905 elf_entry = load_elf_interp(&loc->interp_elf_ex,
1028 } else { 906 interpreter,
1029 unsigned long uninitialized_var(interp_map_addr); 907 &interp_map_addr,
1030 908 load_bias);
1031 elf_entry = load_elf_interp(&loc->interp_elf_ex, 909 if (!IS_ERR((void *)elf_entry)) {
1032 interpreter, 910 /*
1033 &interp_map_addr, 911 * load_elf_interp() returns relocation
1034 load_bias); 912 * adjustment
1035 if (!IS_ERR((void *)elf_entry)) { 913 */
1036 /* 914 interp_load_addr = elf_entry;
1037 * load_elf_interp() returns relocation 915 elf_entry += loc->interp_elf_ex.e_entry;
1038 * adjustment
1039 */
1040 interp_load_addr = elf_entry;
1041 elf_entry += loc->interp_elf_ex.e_entry;
1042 }
1043 } 916 }
1044 if (BAD_ADDR(elf_entry)) { 917 if (BAD_ADDR(elf_entry)) {
1045 force_sig(SIGSEGV, current); 918 force_sig(SIGSEGV, current);
@@ -1063,8 +936,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1063 936
1064 kfree(elf_phdata); 937 kfree(elf_phdata);
1065 938
1066 if (!IS_AOUT_INTERP(interpreter_type)) 939 sys_close(elf_exec_fileno);
1067 sys_close(elf_exec_fileno);
1068 940
1069 set_binfmt(&elf_format); 941 set_binfmt(&elf_format);
1070 942
@@ -1079,15 +951,12 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1079 compute_creds(bprm); 951 compute_creds(bprm);
1080 current->flags &= ~PF_FORKNOEXEC; 952 current->flags &= ~PF_FORKNOEXEC;
1081 retval = create_elf_tables(bprm, &loc->elf_ex, 953 retval = create_elf_tables(bprm, &loc->elf_ex,
1082 IS_AOUT_INTERP(interpreter_type),
1083 load_addr, interp_load_addr); 954 load_addr, interp_load_addr);
1084 if (retval < 0) { 955 if (retval < 0) {
1085 send_sig(SIGKILL, current, 0); 956 send_sig(SIGKILL, current, 0);
1086 goto out; 957 goto out;
1087 } 958 }
1088 /* N.B. passed_fileno might not be initialized? */ 959 /* N.B. passed_fileno might not be initialized? */
1089 if (IS_AOUT_INTERP(interpreter_type))
1090 current->mm->arg_start += strlen(passed_fileno) + 1;
1091 current->mm->end_code = end_code; 960 current->mm->end_code = end_code;
1092 current->mm->start_code = start_code; 961 current->mm->start_code = start_code;
1093 current->mm->start_data = start_data; 962 current->mm->start_data = start_data;