diff options
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 64 |
1 files changed, 19 insertions, 45 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index b9b3bb51b1e4..fd5b2ea5d299 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -44,8 +44,8 @@ static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, | |||
44 | * If we don't support core dumping, then supply a NULL so we | 44 | * If we don't support core dumping, then supply a NULL so we |
45 | * don't even try. | 45 | * don't even try. |
46 | */ | 46 | */ |
47 | #if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) | 47 | #ifdef CONFIG_ELF_CORE |
48 | static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); | 48 | static int elf_core_dump(struct coredump_params *cprm); |
49 | #else | 49 | #else |
50 | #define elf_core_dump NULL | 50 | #define elf_core_dump NULL |
51 | #endif | 51 | #endif |
@@ -662,27 +662,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
662 | if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') | 662 | if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') |
663 | goto out_free_interp; | 663 | goto out_free_interp; |
664 | 664 | ||
665 | /* | ||
666 | * The early SET_PERSONALITY here is so that the lookup | ||
667 | * for the interpreter happens in the namespace of the | ||
668 | * to-be-execed image. SET_PERSONALITY can select an | ||
669 | * alternate root. | ||
670 | * | ||
671 | * However, SET_PERSONALITY is NOT allowed to switch | ||
672 | * this task into the new images's memory mapping | ||
673 | * policy - that is, TASK_SIZE must still evaluate to | ||
674 | * that which is appropriate to the execing application. | ||
675 | * This is because exit_mmap() needs to have TASK_SIZE | ||
676 | * evaluate to the size of the old image. | ||
677 | * | ||
678 | * So if (say) a 64-bit application is execing a 32-bit | ||
679 | * application it is the architecture's responsibility | ||
680 | * to defer changing the value of TASK_SIZE until the | ||
681 | * switch really is going to happen - do this in | ||
682 | * flush_thread(). - akpm | ||
683 | */ | ||
684 | SET_PERSONALITY(loc->elf_ex); | ||
685 | |||
686 | interpreter = open_exec(elf_interpreter); | 665 | interpreter = open_exec(elf_interpreter); |
687 | retval = PTR_ERR(interpreter); | 666 | retval = PTR_ERR(interpreter); |
688 | if (IS_ERR(interpreter)) | 667 | if (IS_ERR(interpreter)) |
@@ -730,9 +709,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
730 | /* Verify the interpreter has a valid arch */ | 709 | /* Verify the interpreter has a valid arch */ |
731 | if (!elf_check_arch(&loc->interp_elf_ex)) | 710 | if (!elf_check_arch(&loc->interp_elf_ex)) |
732 | goto out_free_dentry; | 711 | goto out_free_dentry; |
733 | } else { | ||
734 | /* Executables without an interpreter also need a personality */ | ||
735 | SET_PERSONALITY(loc->elf_ex); | ||
736 | } | 712 | } |
737 | 713 | ||
738 | /* Flush all traces of the currently running executable */ | 714 | /* Flush all traces of the currently running executable */ |
@@ -752,7 +728,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
752 | 728 | ||
753 | if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) | 729 | if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) |
754 | current->flags |= PF_RANDOMIZE; | 730 | current->flags |= PF_RANDOMIZE; |
755 | arch_pick_mmap_layout(current->mm); | 731 | |
732 | setup_new_exec(bprm); | ||
756 | 733 | ||
757 | /* Do this so that we can load the interpreter, if need be. We will | 734 | /* Do this so that we can load the interpreter, if need be. We will |
758 | change some of these later */ | 735 | change some of these later */ |
@@ -767,7 +744,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
767 | 744 | ||
768 | current->mm->start_stack = bprm->p; | 745 | current->mm->start_stack = bprm->p; |
769 | 746 | ||
770 | /* Now we do a little grungy work by mmaping the ELF image into | 747 | /* Now we do a little grungy work by mmapping the ELF image into |
771 | the correct location in memory. */ | 748 | the correct location in memory. */ |
772 | for(i = 0, elf_ppnt = elf_phdata; | 749 | for(i = 0, elf_ppnt = elf_phdata; |
773 | i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { | 750 | i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { |
@@ -1101,12 +1078,7 @@ out: | |||
1101 | return error; | 1078 | return error; |
1102 | } | 1079 | } |
1103 | 1080 | ||
1104 | /* | 1081 | #ifdef CONFIG_ELF_CORE |
1105 | * Note that some platforms still use traditional core dumps and not | ||
1106 | * the ELF core dump. Each platform can select it as appropriate. | ||
1107 | */ | ||
1108 | #if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) | ||
1109 | |||
1110 | /* | 1082 | /* |
1111 | * ELF core dumper | 1083 | * ELF core dumper |
1112 | * | 1084 | * |
@@ -1277,8 +1249,9 @@ static int writenote(struct memelfnote *men, struct file *file, | |||
1277 | } | 1249 | } |
1278 | #undef DUMP_WRITE | 1250 | #undef DUMP_WRITE |
1279 | 1251 | ||
1280 | #define DUMP_WRITE(addr, nr) \ | 1252 | #define DUMP_WRITE(addr, nr) \ |
1281 | if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ | 1253 | if ((size += (nr)) > cprm->limit || \ |
1254 | !dump_write(cprm->file, (addr), (nr))) \ | ||
1282 | goto end_coredump; | 1255 | goto end_coredump; |
1283 | 1256 | ||
1284 | static void fill_elf_header(struct elfhdr *elf, int segs, | 1257 | static void fill_elf_header(struct elfhdr *elf, int segs, |
@@ -1906,7 +1879,7 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, | |||
1906 | * and then they are actually written out. If we run out of core limit | 1879 | * and then they are actually written out. If we run out of core limit |
1907 | * we just truncate. | 1880 | * we just truncate. |
1908 | */ | 1881 | */ |
1909 | static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) | 1882 | static int elf_core_dump(struct coredump_params *cprm) |
1910 | { | 1883 | { |
1911 | int has_dumped = 0; | 1884 | int has_dumped = 0; |
1912 | mm_segment_t fs; | 1885 | mm_segment_t fs; |
@@ -1952,7 +1925,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
1952 | * notes. This also sets up the file header. | 1925 | * notes. This also sets up the file header. |
1953 | */ | 1926 | */ |
1954 | if (!fill_note_info(elf, segs + 1, /* including notes section */ | 1927 | if (!fill_note_info(elf, segs + 1, /* including notes section */ |
1955 | &info, signr, regs)) | 1928 | &info, cprm->signr, cprm->regs)) |
1956 | goto cleanup; | 1929 | goto cleanup; |
1957 | 1930 | ||
1958 | has_dumped = 1; | 1931 | has_dumped = 1; |
@@ -2014,14 +1987,14 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
2014 | #endif | 1987 | #endif |
2015 | 1988 | ||
2016 | /* write out the notes section */ | 1989 | /* write out the notes section */ |
2017 | if (!write_note_info(&info, file, &foffset)) | 1990 | if (!write_note_info(&info, cprm->file, &foffset)) |
2018 | goto end_coredump; | 1991 | goto end_coredump; |
2019 | 1992 | ||
2020 | if (elf_coredump_extra_notes_write(file, &foffset)) | 1993 | if (elf_coredump_extra_notes_write(cprm->file, &foffset)) |
2021 | goto end_coredump; | 1994 | goto end_coredump; |
2022 | 1995 | ||
2023 | /* Align to page */ | 1996 | /* Align to page */ |
2024 | if (!dump_seek(file, dataoff - foffset)) | 1997 | if (!dump_seek(cprm->file, dataoff - foffset)) |
2025 | goto end_coredump; | 1998 | goto end_coredump; |
2026 | 1999 | ||
2027 | for (vma = first_vma(current, gate_vma); vma != NULL; | 2000 | for (vma = first_vma(current, gate_vma); vma != NULL; |
@@ -2038,12 +2011,13 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
2038 | page = get_dump_page(addr); | 2011 | page = get_dump_page(addr); |
2039 | if (page) { | 2012 | if (page) { |
2040 | void *kaddr = kmap(page); | 2013 | void *kaddr = kmap(page); |
2041 | stop = ((size += PAGE_SIZE) > limit) || | 2014 | stop = ((size += PAGE_SIZE) > cprm->limit) || |
2042 | !dump_write(file, kaddr, PAGE_SIZE); | 2015 | !dump_write(cprm->file, kaddr, |
2016 | PAGE_SIZE); | ||
2043 | kunmap(page); | 2017 | kunmap(page); |
2044 | page_cache_release(page); | 2018 | page_cache_release(page); |
2045 | } else | 2019 | } else |
2046 | stop = !dump_seek(file, PAGE_SIZE); | 2020 | stop = !dump_seek(cprm->file, PAGE_SIZE); |
2047 | if (stop) | 2021 | if (stop) |
2048 | goto end_coredump; | 2022 | goto end_coredump; |
2049 | } | 2023 | } |
@@ -2063,7 +2037,7 @@ out: | |||
2063 | return has_dumped; | 2037 | return has_dumped; |
2064 | } | 2038 | } |
2065 | 2039 | ||
2066 | #endif /* USE_ELF_CORE_DUMP */ | 2040 | #endif /* CONFIG_ELF_CORE */ |
2067 | 2041 | ||
2068 | static int __init init_elf_binfmt(void) | 2042 | static int __init init_elf_binfmt(void) |
2069 | { | 2043 | { |