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.c157
1 files changed, 22 insertions, 135 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 4628c42ca892..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,59 +499,12 @@ out:
513 return error; 499 return error;
514} 500}
515 501
516static unsigned long load_aout_interp(struct exec *interp_ex,
517 struct file *interpreter)
518{
519 unsigned long text_data, elf_entry = ~0UL;
520 char __user * addr;
521 loff_t offset;
522
523 current->mm->end_code = interp_ex->a_text;
524 text_data = interp_ex->a_text + interp_ex->a_data;
525 current->mm->end_data = text_data;
526 current->mm->brk = interp_ex->a_bss + text_data;
527
528 switch (N_MAGIC(*interp_ex)) {
529 case OMAGIC:
530 offset = 32;
531 addr = (char __user *)0;
532 break;
533 case ZMAGIC:
534 case QMAGIC:
535 offset = N_TXTOFF(*interp_ex);
536 addr = (char __user *)N_TXTADDR(*interp_ex);
537 break;
538 default:
539 goto out;
540 }
541
542 down_write(&current->mm->mmap_sem);
543 do_brk(0, text_data);
544 up_write(&current->mm->mmap_sem);
545 if (!interpreter->f_op || !interpreter->f_op->read)
546 goto out;
547 if (interpreter->f_op->read(interpreter, addr, text_data, &offset) < 0)
548 goto out;
549 flush_icache_range((unsigned long)addr,
550 (unsigned long)addr + text_data);
551
552 down_write(&current->mm->mmap_sem);
553 do_brk(ELF_PAGESTART(text_data + ELF_MIN_ALIGN - 1),
554 interp_ex->a_bss);
555 up_write(&current->mm->mmap_sem);
556 elf_entry = interp_ex->a_entry;
557
558out:
559 return elf_entry;
560}
561
562/* 502/*
563 * 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
564 * libraries. There is no binary dependent code anywhere else. 504 * libraries. There is no binary dependent code anywhere else.
565 */ 505 */
566 506
567#define INTERPRETER_NONE 0 507#define INTERPRETER_NONE 0
568#define INTERPRETER_AOUT 1
569#define INTERPRETER_ELF 2 508#define INTERPRETER_ELF 2
570 509
571#ifndef STACK_RND_MASK 510#ifndef STACK_RND_MASK
@@ -594,7 +533,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
594 unsigned long load_addr = 0, load_bias = 0; 533 unsigned long load_addr = 0, load_bias = 0;
595 int load_addr_set = 0; 534 int load_addr_set = 0;
596 char * elf_interpreter = NULL; 535 char * elf_interpreter = NULL;
597 unsigned int interpreter_type = INTERPRETER_NONE;
598 unsigned long error; 536 unsigned long error;
599 struct elf_phdr *elf_ppnt, *elf_phdata; 537 struct elf_phdr *elf_ppnt, *elf_phdata;
600 unsigned long elf_bss, elf_brk; 538 unsigned long elf_bss, elf_brk;
@@ -605,7 +543,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
605 unsigned long interp_load_addr = 0; 543 unsigned long interp_load_addr = 0;
606 unsigned long start_code, end_code, start_data, end_data; 544 unsigned long start_code, end_code, start_data, end_data;
607 unsigned long reloc_func_desc = 0; 545 unsigned long reloc_func_desc = 0;
608 char passed_fileno[6];
609 struct files_struct *files; 546 struct files_struct *files;
610 int executable_stack = EXSTACK_DEFAULT; 547 int executable_stack = EXSTACK_DEFAULT;
611 unsigned long def_flags = 0; 548 unsigned long def_flags = 0;
@@ -774,59 +711,18 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
774 711
775 /* Some simple consistency checks for the interpreter */ 712 /* Some simple consistency checks for the interpreter */
776 if (elf_interpreter) { 713 if (elf_interpreter) {
777 static int warn;
778 interpreter_type = INTERPRETER_ELF | INTERPRETER_AOUT;
779
780 /* Now figure out which format our binary is */
781 if ((N_MAGIC(loc->interp_ex) != OMAGIC) &&
782 (N_MAGIC(loc->interp_ex) != ZMAGIC) &&
783 (N_MAGIC(loc->interp_ex) != QMAGIC))
784 interpreter_type = INTERPRETER_ELF;
785
786 if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
787 interpreter_type &= ~INTERPRETER_ELF;
788
789 if (interpreter_type == INTERPRETER_AOUT && warn < 10) {
790 printk(KERN_WARNING "a.out ELF interpreter %s is "
791 "deprecated and will not be supported "
792 "after Linux 2.6.25\n", elf_interpreter);
793 warn++;
794 }
795
796 retval = -ELIBBAD; 714 retval = -ELIBBAD;
797 if (!interpreter_type) 715 /* Not an ELF interpreter */
716 if (memcmp(loc->interp_elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
798 goto out_free_dentry; 717 goto out_free_dentry;
799
800 /* Make sure only one type was selected */
801 if ((interpreter_type & INTERPRETER_ELF) &&
802 interpreter_type != INTERPRETER_ELF) {
803 // FIXME - ratelimit this before re-enabling
804 // printk(KERN_WARNING "ELF: Ambiguous type, using ELF\n");
805 interpreter_type = INTERPRETER_ELF;
806 }
807 /* Verify the interpreter has a valid arch */ 718 /* Verify the interpreter has a valid arch */
808 if ((interpreter_type == INTERPRETER_ELF) && 719 if (!elf_check_arch(&loc->interp_elf_ex))
809 !elf_check_arch(&loc->interp_elf_ex))
810 goto out_free_dentry; 720 goto out_free_dentry;
811 } else { 721 } else {
812 /* Executables without an interpreter also need a personality */ 722 /* Executables without an interpreter also need a personality */
813 SET_PERSONALITY(loc->elf_ex, 0); 723 SET_PERSONALITY(loc->elf_ex, 0);
814 } 724 }
815 725
816 /* OK, we are done with that, now set up the arg stuff,
817 and then start this sucker up */
818 if ((!bprm->sh_bang) && (interpreter_type == INTERPRETER_AOUT)) {
819 char *passed_p = passed_fileno;
820 sprintf(passed_fileno, "%d", elf_exec_fileno);
821
822 if (elf_interpreter) {
823 retval = copy_strings_kernel(1, &passed_p, bprm);
824 if (retval)
825 goto out_free_dentry;
826 bprm->argc++;
827 }
828 }
829
830 /* Flush all traces of the currently running executable */ 726 /* Flush all traces of the currently running executable */
831 retval = flush_old_exec(bprm); 727 retval = flush_old_exec(bprm);
832 if (retval) 728 if (retval)
@@ -1004,24 +900,19 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1004 } 900 }
1005 901
1006 if (elf_interpreter) { 902 if (elf_interpreter) {
1007 if (interpreter_type == INTERPRETER_AOUT) { 903 unsigned long uninitialized_var(interp_map_addr);
1008 elf_entry = load_aout_interp(&loc->interp_ex, 904
1009 interpreter); 905 elf_entry = load_elf_interp(&loc->interp_elf_ex,
1010 } else { 906 interpreter,
1011 unsigned long uninitialized_var(interp_map_addr); 907 &interp_map_addr,
1012 908 load_bias);
1013 elf_entry = load_elf_interp(&loc->interp_elf_ex, 909 if (!IS_ERR((void *)elf_entry)) {
1014 interpreter, 910 /*
1015 &interp_map_addr, 911 * load_elf_interp() returns relocation
1016 load_bias); 912 * adjustment
1017 if (!IS_ERR((void *)elf_entry)) { 913 */
1018 /* 914 interp_load_addr = elf_entry;
1019 * load_elf_interp() returns relocation 915 elf_entry += loc->interp_elf_ex.e_entry;
1020 * adjustment
1021 */
1022 interp_load_addr = elf_entry;
1023 elf_entry += loc->interp_elf_ex.e_entry;
1024 }
1025 } 916 }
1026 if (BAD_ADDR(elf_entry)) { 917 if (BAD_ADDR(elf_entry)) {
1027 force_sig(SIGSEGV, current); 918 force_sig(SIGSEGV, current);
@@ -1045,8 +936,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1045 936
1046 kfree(elf_phdata); 937 kfree(elf_phdata);
1047 938
1048 if (interpreter_type != INTERPRETER_AOUT) 939 sys_close(elf_exec_fileno);
1049 sys_close(elf_exec_fileno);
1050 940
1051 set_binfmt(&elf_format); 941 set_binfmt(&elf_format);
1052 942
@@ -1061,15 +951,12 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1061 compute_creds(bprm); 951 compute_creds(bprm);
1062 current->flags &= ~PF_FORKNOEXEC; 952 current->flags &= ~PF_FORKNOEXEC;
1063 retval = create_elf_tables(bprm, &loc->elf_ex, 953 retval = create_elf_tables(bprm, &loc->elf_ex,
1064 (interpreter_type == INTERPRETER_AOUT),
1065 load_addr, interp_load_addr); 954 load_addr, interp_load_addr);
1066 if (retval < 0) { 955 if (retval < 0) {
1067 send_sig(SIGKILL, current, 0); 956 send_sig(SIGKILL, current, 0);
1068 goto out; 957 goto out;
1069 } 958 }
1070 /* N.B. passed_fileno might not be initialized? */ 959 /* N.B. passed_fileno might not be initialized? */
1071 if (interpreter_type == INTERPRETER_AOUT)
1072 current->mm->arg_start += strlen(passed_fileno) + 1;
1073 current->mm->end_code = end_code; 960 current->mm->end_code = end_code;
1074 current->mm->start_code = start_code; 961 current->mm->start_code = start_code;
1075 current->mm->start_data = start_data; 962 current->mm->start_data = start_data;
@@ -1077,7 +964,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
1077 current->mm->start_stack = bprm->p; 964 current->mm->start_stack = bprm->p;
1078 965
1079#ifdef arch_randomize_brk 966#ifdef arch_randomize_brk
1080 if (current->flags & PF_RANDOMIZE) 967 if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1))
1081 current->mm->brk = current->mm->start_brk = 968 current->mm->brk = current->mm->start_brk =
1082 arch_randomize_brk(current->mm); 969 arch_randomize_brk(current->mm);
1083#endif 970#endif