diff options
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 7b055385db8e..18d77297ccc8 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -76,7 +76,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *, | |||
76 | struct file *, struct mm_struct *); | 76 | struct file *, struct mm_struct *); |
77 | 77 | ||
78 | #ifdef CONFIG_ELF_CORE | 78 | #ifdef CONFIG_ELF_CORE |
79 | static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *, unsigned long limit); | 79 | static int elf_fdpic_core_dump(struct coredump_params *cprm); |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | static struct linux_binfmt elf_fdpic_format = { | 82 | static struct linux_binfmt elf_fdpic_format = { |
@@ -171,6 +171,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
171 | #ifdef ELF_FDPIC_PLAT_INIT | 171 | #ifdef ELF_FDPIC_PLAT_INIT |
172 | unsigned long dynaddr; | 172 | unsigned long dynaddr; |
173 | #endif | 173 | #endif |
174 | #ifndef CONFIG_MMU | ||
175 | unsigned long stack_prot; | ||
176 | #endif | ||
174 | struct file *interpreter = NULL; /* to shut gcc up */ | 177 | struct file *interpreter = NULL; /* to shut gcc up */ |
175 | char *interpreter_name = NULL; | 178 | char *interpreter_name = NULL; |
176 | int executable_stack; | 179 | int executable_stack; |
@@ -316,6 +319,11 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
316 | * defunct, deceased, etc. after this point we have to exit via | 319 | * defunct, deceased, etc. after this point we have to exit via |
317 | * error_kill */ | 320 | * error_kill */ |
318 | set_personality(PER_LINUX_FDPIC); | 321 | set_personality(PER_LINUX_FDPIC); |
322 | if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) | ||
323 | current->personality |= READ_IMPLIES_EXEC; | ||
324 | |||
325 | setup_new_exec(bprm); | ||
326 | |||
319 | set_binfmt(&elf_fdpic_format); | 327 | set_binfmt(&elf_fdpic_format); |
320 | 328 | ||
321 | current->mm->start_code = 0; | 329 | current->mm->start_code = 0; |
@@ -377,9 +385,13 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
377 | if (stack_size < PAGE_SIZE * 2) | 385 | if (stack_size < PAGE_SIZE * 2) |
378 | stack_size = PAGE_SIZE * 2; | 386 | stack_size = PAGE_SIZE * 2; |
379 | 387 | ||
388 | stack_prot = PROT_READ | PROT_WRITE; | ||
389 | if (executable_stack == EXSTACK_ENABLE_X || | ||
390 | (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) | ||
391 | stack_prot |= PROT_EXEC; | ||
392 | |||
380 | down_write(¤t->mm->mmap_sem); | 393 | down_write(¤t->mm->mmap_sem); |
381 | current->mm->start_brk = do_mmap(NULL, 0, stack_size, | 394 | current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, |
382 | PROT_READ | PROT_WRITE | PROT_EXEC, | ||
383 | MAP_PRIVATE | MAP_ANONYMOUS | | 395 | MAP_PRIVATE | MAP_ANONYMOUS | |
384 | MAP_UNINITIALIZED | MAP_GROWSDOWN, | 396 | MAP_UNINITIALIZED | MAP_GROWSDOWN, |
385 | 0); | 397 | 0); |
@@ -1326,8 +1338,9 @@ static int writenote(struct memelfnote *men, struct file *file) | |||
1326 | #undef DUMP_WRITE | 1338 | #undef DUMP_WRITE |
1327 | #undef DUMP_SEEK | 1339 | #undef DUMP_SEEK |
1328 | 1340 | ||
1329 | #define DUMP_WRITE(addr, nr) \ | 1341 | #define DUMP_WRITE(addr, nr) \ |
1330 | if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ | 1342 | if ((size += (nr)) > cprm->limit || \ |
1343 | !dump_write(cprm->file, (addr), (nr))) \ | ||
1331 | goto end_coredump; | 1344 | goto end_coredump; |
1332 | 1345 | ||
1333 | static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) | 1346 | static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) |
@@ -1582,8 +1595,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size, | |||
1582 | * and then they are actually written out. If we run out of core limit | 1595 | * and then they are actually written out. If we run out of core limit |
1583 | * we just truncate. | 1596 | * we just truncate. |
1584 | */ | 1597 | */ |
1585 | static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | 1598 | static int elf_fdpic_core_dump(struct coredump_params *cprm) |
1586 | struct file *file, unsigned long limit) | ||
1587 | { | 1599 | { |
1588 | #define NUM_NOTES 6 | 1600 | #define NUM_NOTES 6 |
1589 | int has_dumped = 0; | 1601 | int has_dumped = 0; |
@@ -1642,7 +1654,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1642 | goto cleanup; | 1654 | goto cleanup; |
1643 | #endif | 1655 | #endif |
1644 | 1656 | ||
1645 | if (signr) { | 1657 | if (cprm->signr) { |
1646 | struct core_thread *ct; | 1658 | struct core_thread *ct; |
1647 | struct elf_thread_status *tmp; | 1659 | struct elf_thread_status *tmp; |
1648 | 1660 | ||
@@ -1661,14 +1673,14 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1661 | int sz; | 1673 | int sz; |
1662 | 1674 | ||
1663 | tmp = list_entry(t, struct elf_thread_status, list); | 1675 | tmp = list_entry(t, struct elf_thread_status, list); |
1664 | sz = elf_dump_thread_status(signr, tmp); | 1676 | sz = elf_dump_thread_status(cprm->signr, tmp); |
1665 | thread_status_size += sz; | 1677 | thread_status_size += sz; |
1666 | } | 1678 | } |
1667 | } | 1679 | } |
1668 | 1680 | ||
1669 | /* now collect the dump for the current */ | 1681 | /* now collect the dump for the current */ |
1670 | fill_prstatus(prstatus, current, signr); | 1682 | fill_prstatus(prstatus, current, cprm->signr); |
1671 | elf_core_copy_regs(&prstatus->pr_reg, regs); | 1683 | elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); |
1672 | 1684 | ||
1673 | segs = current->mm->map_count; | 1685 | segs = current->mm->map_count; |
1674 | #ifdef ELF_CORE_EXTRA_PHDRS | 1686 | #ifdef ELF_CORE_EXTRA_PHDRS |
@@ -1703,7 +1715,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1703 | 1715 | ||
1704 | /* Try to dump the FPU. */ | 1716 | /* Try to dump the FPU. */ |
1705 | if ((prstatus->pr_fpvalid = | 1717 | if ((prstatus->pr_fpvalid = |
1706 | elf_core_copy_task_fpregs(current, regs, fpu))) | 1718 | elf_core_copy_task_fpregs(current, cprm->regs, fpu))) |
1707 | fill_note(notes + numnote++, | 1719 | fill_note(notes + numnote++, |
1708 | "CORE", NT_PRFPREG, sizeof(*fpu), fpu); | 1720 | "CORE", NT_PRFPREG, sizeof(*fpu), fpu); |
1709 | #ifdef ELF_CORE_COPY_XFPREGS | 1721 | #ifdef ELF_CORE_COPY_XFPREGS |
@@ -1774,7 +1786,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1774 | 1786 | ||
1775 | /* write out the notes section */ | 1787 | /* write out the notes section */ |
1776 | for (i = 0; i < numnote; i++) | 1788 | for (i = 0; i < numnote; i++) |
1777 | if (!writenote(notes + i, file)) | 1789 | if (!writenote(notes + i, cprm->file)) |
1778 | goto end_coredump; | 1790 | goto end_coredump; |
1779 | 1791 | ||
1780 | /* write out the thread status notes section */ | 1792 | /* write out the thread status notes section */ |
@@ -1783,25 +1795,26 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1783 | list_entry(t, struct elf_thread_status, list); | 1795 | list_entry(t, struct elf_thread_status, list); |
1784 | 1796 | ||
1785 | for (i = 0; i < tmp->num_notes; i++) | 1797 | for (i = 0; i < tmp->num_notes; i++) |
1786 | if (!writenote(&tmp->notes[i], file)) | 1798 | if (!writenote(&tmp->notes[i], cprm->file)) |
1787 | goto end_coredump; | 1799 | goto end_coredump; |
1788 | } | 1800 | } |
1789 | 1801 | ||
1790 | if (!dump_seek(file, dataoff)) | 1802 | if (!dump_seek(cprm->file, dataoff)) |
1791 | goto end_coredump; | 1803 | goto end_coredump; |
1792 | 1804 | ||
1793 | if (elf_fdpic_dump_segments(file, &size, &limit, mm_flags) < 0) | 1805 | if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit, |
1806 | mm_flags) < 0) | ||
1794 | goto end_coredump; | 1807 | goto end_coredump; |
1795 | 1808 | ||
1796 | #ifdef ELF_CORE_WRITE_EXTRA_DATA | 1809 | #ifdef ELF_CORE_WRITE_EXTRA_DATA |
1797 | ELF_CORE_WRITE_EXTRA_DATA; | 1810 | ELF_CORE_WRITE_EXTRA_DATA; |
1798 | #endif | 1811 | #endif |
1799 | 1812 | ||
1800 | if (file->f_pos != offset) { | 1813 | if (cprm->file->f_pos != offset) { |
1801 | /* Sanity check */ | 1814 | /* Sanity check */ |
1802 | printk(KERN_WARNING | 1815 | printk(KERN_WARNING |
1803 | "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n", | 1816 | "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n", |
1804 | file->f_pos, offset); | 1817 | cprm->file->f_pos, offset); |
1805 | } | 1818 | } |
1806 | 1819 | ||
1807 | end_coredump: | 1820 | end_coredump: |