diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-12-17 18:27:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-17 18:45:31 -0500 |
commit | f6151dfea21496d43dbaba32cfcd9c9f404769bc (patch) | |
tree | 092b73a1cd7edbd0e04fe2076ed678447446aa70 | |
parent | 9cd80bbb07fcd6d4d037fad4297496d3b132ac6b (diff) |
mm: introduce coredump parameter structure
Introduce coredump parameter data structure (struct coredump_params) to
simplify binfmt->core_dump() arguments.
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Suggested-by: Ingo Molnar <mingo@elte.hu>
Cc: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Roland McGrath <roland@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/binfmt_aout.c | 13 | ||||
-rw-r--r-- | fs/binfmt_elf.c | 24 | ||||
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 29 | ||||
-rw-r--r-- | fs/binfmt_flat.c | 6 | ||||
-rw-r--r-- | fs/binfmt_som.c | 2 | ||||
-rw-r--r-- | fs/exec.c | 38 | ||||
-rw-r--r-- | include/linux/binfmts.h | 10 |
7 files changed, 69 insertions, 53 deletions
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index b639dcf7c778..346b69405363 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); | 33 | static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs); |
34 | static int load_aout_library(struct file*); | 34 | static int load_aout_library(struct file*); |
35 | static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); | 35 | static int aout_core_dump(struct coredump_params *cprm); |
36 | 36 | ||
37 | static struct linux_binfmt aout_format = { | 37 | static struct linux_binfmt aout_format = { |
38 | .module = THIS_MODULE, | 38 | .module = THIS_MODULE, |
@@ -89,8 +89,9 @@ if (file->f_op->llseek) { \ | |||
89 | * dumping of the process results in another error.. | 89 | * dumping of the process results in another error.. |
90 | */ | 90 | */ |
91 | 91 | ||
92 | static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) | 92 | static int aout_core_dump(struct coredump_params *cprm) |
93 | { | 93 | { |
94 | struct file *file = cprm->file; | ||
94 | mm_segment_t fs; | 95 | mm_segment_t fs; |
95 | int has_dumped = 0; | 96 | int has_dumped = 0; |
96 | unsigned long dump_start, dump_size; | 97 | unsigned long dump_start, dump_size; |
@@ -108,16 +109,16 @@ static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, u | |||
108 | current->flags |= PF_DUMPCORE; | 109 | current->flags |= PF_DUMPCORE; |
109 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); | 110 | strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm)); |
110 | dump.u_ar0 = offsetof(struct user, regs); | 111 | dump.u_ar0 = offsetof(struct user, regs); |
111 | dump.signal = signr; | 112 | dump.signal = cprm->signr; |
112 | aout_dump_thread(regs, &dump); | 113 | aout_dump_thread(cprm->regs, &dump); |
113 | 114 | ||
114 | /* If the size of the dump file exceeds the rlimit, then see what would happen | 115 | /* If the size of the dump file exceeds the rlimit, then see what would happen |
115 | if we wrote the stack, but not the data area. */ | 116 | if we wrote the stack, but not the data area. */ |
116 | if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit) | 117 | if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > cprm->limit) |
117 | dump.u_dsize = 0; | 118 | dump.u_dsize = 0; |
118 | 119 | ||
119 | /* Make sure we have enough room to write the stack and data areas. */ | 120 | /* Make sure we have enough room to write the stack and data areas. */ |
120 | if ((dump.u_ssize + 1) * PAGE_SIZE > limit) | 121 | if ((dump.u_ssize + 1) * PAGE_SIZE > cprm->limit) |
121 | dump.u_ssize = 0; | 122 | dump.u_ssize = 0; |
122 | 123 | ||
123 | /* make sure we actually have a data and stack area to dump */ | 124 | /* make sure we actually have a data and stack area to dump */ |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 97b6e9efeb7f..edd90c49003c 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -45,7 +45,7 @@ static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *, | |||
45 | * don't even try. | 45 | * don't even try. |
46 | */ | 46 | */ |
47 | #ifdef 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 |
@@ -1272,8 +1272,9 @@ static int writenote(struct memelfnote *men, struct file *file, | |||
1272 | } | 1272 | } |
1273 | #undef DUMP_WRITE | 1273 | #undef DUMP_WRITE |
1274 | 1274 | ||
1275 | #define DUMP_WRITE(addr, nr) \ | 1275 | #define DUMP_WRITE(addr, nr) \ |
1276 | if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ | 1276 | if ((size += (nr)) > cprm->limit || \ |
1277 | !dump_write(cprm->file, (addr), (nr))) \ | ||
1277 | goto end_coredump; | 1278 | goto end_coredump; |
1278 | 1279 | ||
1279 | static void fill_elf_header(struct elfhdr *elf, int segs, | 1280 | static void fill_elf_header(struct elfhdr *elf, int segs, |
@@ -1901,7 +1902,7 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, | |||
1901 | * and then they are actually written out. If we run out of core limit | 1902 | * and then they are actually written out. If we run out of core limit |
1902 | * we just truncate. | 1903 | * we just truncate. |
1903 | */ | 1904 | */ |
1904 | static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) | 1905 | static int elf_core_dump(struct coredump_params *cprm) |
1905 | { | 1906 | { |
1906 | int has_dumped = 0; | 1907 | int has_dumped = 0; |
1907 | mm_segment_t fs; | 1908 | mm_segment_t fs; |
@@ -1947,7 +1948,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
1947 | * notes. This also sets up the file header. | 1948 | * notes. This also sets up the file header. |
1948 | */ | 1949 | */ |
1949 | if (!fill_note_info(elf, segs + 1, /* including notes section */ | 1950 | if (!fill_note_info(elf, segs + 1, /* including notes section */ |
1950 | &info, signr, regs)) | 1951 | &info, cprm->signr, cprm->regs)) |
1951 | goto cleanup; | 1952 | goto cleanup; |
1952 | 1953 | ||
1953 | has_dumped = 1; | 1954 | has_dumped = 1; |
@@ -2009,14 +2010,14 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
2009 | #endif | 2010 | #endif |
2010 | 2011 | ||
2011 | /* write out the notes section */ | 2012 | /* write out the notes section */ |
2012 | if (!write_note_info(&info, file, &foffset)) | 2013 | if (!write_note_info(&info, cprm->file, &foffset)) |
2013 | goto end_coredump; | 2014 | goto end_coredump; |
2014 | 2015 | ||
2015 | if (elf_coredump_extra_notes_write(file, &foffset)) | 2016 | if (elf_coredump_extra_notes_write(cprm->file, &foffset)) |
2016 | goto end_coredump; | 2017 | goto end_coredump; |
2017 | 2018 | ||
2018 | /* Align to page */ | 2019 | /* Align to page */ |
2019 | if (!dump_seek(file, dataoff - foffset)) | 2020 | if (!dump_seek(cprm->file, dataoff - foffset)) |
2020 | goto end_coredump; | 2021 | goto end_coredump; |
2021 | 2022 | ||
2022 | for (vma = first_vma(current, gate_vma); vma != NULL; | 2023 | for (vma = first_vma(current, gate_vma); vma != NULL; |
@@ -2033,12 +2034,13 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
2033 | page = get_dump_page(addr); | 2034 | page = get_dump_page(addr); |
2034 | if (page) { | 2035 | if (page) { |
2035 | void *kaddr = kmap(page); | 2036 | void *kaddr = kmap(page); |
2036 | stop = ((size += PAGE_SIZE) > limit) || | 2037 | stop = ((size += PAGE_SIZE) > cprm->limit) || |
2037 | !dump_write(file, kaddr, PAGE_SIZE); | 2038 | !dump_write(cprm->file, kaddr, |
2039 | PAGE_SIZE); | ||
2038 | kunmap(page); | 2040 | kunmap(page); |
2039 | page_cache_release(page); | 2041 | page_cache_release(page); |
2040 | } else | 2042 | } else |
2041 | stop = !dump_seek(file, PAGE_SIZE); | 2043 | stop = !dump_seek(cprm->file, PAGE_SIZE); |
2042 | if (stop) | 2044 | if (stop) |
2043 | goto end_coredump; | 2045 | goto end_coredump; |
2044 | } | 2046 | } |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 7b055385db8e..c25256a5c5b0 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 = { |
@@ -1326,8 +1326,9 @@ static int writenote(struct memelfnote *men, struct file *file) | |||
1326 | #undef DUMP_WRITE | 1326 | #undef DUMP_WRITE |
1327 | #undef DUMP_SEEK | 1327 | #undef DUMP_SEEK |
1328 | 1328 | ||
1329 | #define DUMP_WRITE(addr, nr) \ | 1329 | #define DUMP_WRITE(addr, nr) \ |
1330 | if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \ | 1330 | if ((size += (nr)) > cprm->limit || \ |
1331 | !dump_write(cprm->file, (addr), (nr))) \ | ||
1331 | goto end_coredump; | 1332 | goto end_coredump; |
1332 | 1333 | ||
1333 | static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) | 1334 | static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) |
@@ -1582,8 +1583,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 | 1583 | * and then they are actually written out. If we run out of core limit |
1583 | * we just truncate. | 1584 | * we just truncate. |
1584 | */ | 1585 | */ |
1585 | static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | 1586 | static int elf_fdpic_core_dump(struct coredump_params *cprm) |
1586 | struct file *file, unsigned long limit) | ||
1587 | { | 1587 | { |
1588 | #define NUM_NOTES 6 | 1588 | #define NUM_NOTES 6 |
1589 | int has_dumped = 0; | 1589 | int has_dumped = 0; |
@@ -1642,7 +1642,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1642 | goto cleanup; | 1642 | goto cleanup; |
1643 | #endif | 1643 | #endif |
1644 | 1644 | ||
1645 | if (signr) { | 1645 | if (cprm->signr) { |
1646 | struct core_thread *ct; | 1646 | struct core_thread *ct; |
1647 | struct elf_thread_status *tmp; | 1647 | struct elf_thread_status *tmp; |
1648 | 1648 | ||
@@ -1661,14 +1661,14 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1661 | int sz; | 1661 | int sz; |
1662 | 1662 | ||
1663 | tmp = list_entry(t, struct elf_thread_status, list); | 1663 | tmp = list_entry(t, struct elf_thread_status, list); |
1664 | sz = elf_dump_thread_status(signr, tmp); | 1664 | sz = elf_dump_thread_status(cprm->signr, tmp); |
1665 | thread_status_size += sz; | 1665 | thread_status_size += sz; |
1666 | } | 1666 | } |
1667 | } | 1667 | } |
1668 | 1668 | ||
1669 | /* now collect the dump for the current */ | 1669 | /* now collect the dump for the current */ |
1670 | fill_prstatus(prstatus, current, signr); | 1670 | fill_prstatus(prstatus, current, cprm->signr); |
1671 | elf_core_copy_regs(&prstatus->pr_reg, regs); | 1671 | elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); |
1672 | 1672 | ||
1673 | segs = current->mm->map_count; | 1673 | segs = current->mm->map_count; |
1674 | #ifdef ELF_CORE_EXTRA_PHDRS | 1674 | #ifdef ELF_CORE_EXTRA_PHDRS |
@@ -1703,7 +1703,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1703 | 1703 | ||
1704 | /* Try to dump the FPU. */ | 1704 | /* Try to dump the FPU. */ |
1705 | if ((prstatus->pr_fpvalid = | 1705 | if ((prstatus->pr_fpvalid = |
1706 | elf_core_copy_task_fpregs(current, regs, fpu))) | 1706 | elf_core_copy_task_fpregs(current, cprm->regs, fpu))) |
1707 | fill_note(notes + numnote++, | 1707 | fill_note(notes + numnote++, |
1708 | "CORE", NT_PRFPREG, sizeof(*fpu), fpu); | 1708 | "CORE", NT_PRFPREG, sizeof(*fpu), fpu); |
1709 | #ifdef ELF_CORE_COPY_XFPREGS | 1709 | #ifdef ELF_CORE_COPY_XFPREGS |
@@ -1774,7 +1774,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1774 | 1774 | ||
1775 | /* write out the notes section */ | 1775 | /* write out the notes section */ |
1776 | for (i = 0; i < numnote; i++) | 1776 | for (i = 0; i < numnote; i++) |
1777 | if (!writenote(notes + i, file)) | 1777 | if (!writenote(notes + i, cprm->file)) |
1778 | goto end_coredump; | 1778 | goto end_coredump; |
1779 | 1779 | ||
1780 | /* write out the thread status notes section */ | 1780 | /* write out the thread status notes section */ |
@@ -1783,14 +1783,15 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, | |||
1783 | list_entry(t, struct elf_thread_status, list); | 1783 | list_entry(t, struct elf_thread_status, list); |
1784 | 1784 | ||
1785 | for (i = 0; i < tmp->num_notes; i++) | 1785 | for (i = 0; i < tmp->num_notes; i++) |
1786 | if (!writenote(&tmp->notes[i], file)) | 1786 | if (!writenote(&tmp->notes[i], cprm->file)) |
1787 | goto end_coredump; | 1787 | goto end_coredump; |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | if (!dump_seek(file, dataoff)) | 1790 | if (!dump_seek(cprm->file, dataoff)) |
1791 | goto end_coredump; | 1791 | goto end_coredump; |
1792 | 1792 | ||
1793 | if (elf_fdpic_dump_segments(file, &size, &limit, mm_flags) < 0) | 1793 | if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit, |
1794 | mm_flags) < 0) | ||
1794 | goto end_coredump; | 1795 | goto end_coredump; |
1795 | 1796 | ||
1796 | #ifdef ELF_CORE_WRITE_EXTRA_DATA | 1797 | #ifdef ELF_CORE_WRITE_EXTRA_DATA |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index a2796651e756..d4a00ea1054c 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -87,7 +87,7 @@ static int load_flat_shared_library(int id, struct lib_info *p); | |||
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); | 89 | static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); |
90 | static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); | 90 | static int flat_core_dump(struct coredump_params *cprm); |
91 | 91 | ||
92 | static struct linux_binfmt flat_format = { | 92 | static struct linux_binfmt flat_format = { |
93 | .module = THIS_MODULE, | 93 | .module = THIS_MODULE, |
@@ -102,10 +102,10 @@ static struct linux_binfmt flat_format = { | |||
102 | * Currently only a stub-function. | 102 | * Currently only a stub-function. |
103 | */ | 103 | */ |
104 | 104 | ||
105 | static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) | 105 | static int flat_core_dump(struct coredump_params *cprm) |
106 | { | 106 | { |
107 | printk("Process %s:%d received signr %d and should have core dumped\n", | 107 | printk("Process %s:%d received signr %d and should have core dumped\n", |
108 | current->comm, current->pid, (int) signr); | 108 | current->comm, current->pid, (int) cprm->signr); |
109 | return(1); | 109 | return(1); |
110 | } | 110 | } |
111 | 111 | ||
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index eff74b9c9e77..2a9b5330cc5e 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c | |||
@@ -43,7 +43,7 @@ static int load_som_library(struct file *); | |||
43 | * don't even try. | 43 | * don't even try. |
44 | */ | 44 | */ |
45 | #if 0 | 45 | #if 0 |
46 | static int som_core_dump(long signr, struct pt_regs *regs, unsigned long limit); | 46 | static int som_core_dump(struct coredump_params *cprm); |
47 | #else | 47 | #else |
48 | #define som_core_dump NULL | 48 | #define som_core_dump NULL |
49 | #endif | 49 | #endif |
@@ -1763,17 +1763,20 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1763 | struct mm_struct *mm = current->mm; | 1763 | struct mm_struct *mm = current->mm; |
1764 | struct linux_binfmt * binfmt; | 1764 | struct linux_binfmt * binfmt; |
1765 | struct inode * inode; | 1765 | struct inode * inode; |
1766 | struct file * file; | ||
1767 | const struct cred *old_cred; | 1766 | const struct cred *old_cred; |
1768 | struct cred *cred; | 1767 | struct cred *cred; |
1769 | int retval = 0; | 1768 | int retval = 0; |
1770 | int flag = 0; | 1769 | int flag = 0; |
1771 | int ispipe = 0; | 1770 | int ispipe = 0; |
1772 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | ||
1773 | char **helper_argv = NULL; | 1771 | char **helper_argv = NULL; |
1774 | int helper_argc = 0; | 1772 | int helper_argc = 0; |
1775 | int dump_count = 0; | 1773 | int dump_count = 0; |
1776 | static atomic_t core_dump_count = ATOMIC_INIT(0); | 1774 | static atomic_t core_dump_count = ATOMIC_INIT(0); |
1775 | struct coredump_params cprm = { | ||
1776 | .signr = signr, | ||
1777 | .regs = regs, | ||
1778 | .limit = current->signal->rlim[RLIMIT_CORE].rlim_cur, | ||
1779 | }; | ||
1777 | 1780 | ||
1778 | audit_core_dumps(signr); | 1781 | audit_core_dumps(signr); |
1779 | 1782 | ||
@@ -1829,15 +1832,15 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1829 | ispipe = format_corename(corename, signr); | 1832 | ispipe = format_corename(corename, signr); |
1830 | unlock_kernel(); | 1833 | unlock_kernel(); |
1831 | 1834 | ||
1832 | if ((!ispipe) && (core_limit < binfmt->min_coredump)) | 1835 | if ((!ispipe) && (cprm.limit < binfmt->min_coredump)) |
1833 | goto fail_unlock; | 1836 | goto fail_unlock; |
1834 | 1837 | ||
1835 | if (ispipe) { | 1838 | if (ispipe) { |
1836 | if (core_limit == 0) { | 1839 | if (cprm.limit == 0) { |
1837 | /* | 1840 | /* |
1838 | * Normally core limits are irrelevant to pipes, since | 1841 | * Normally core limits are irrelevant to pipes, since |
1839 | * we're not writing to the file system, but we use | 1842 | * we're not writing to the file system, but we use |
1840 | * core_limit of 0 here as a speacial value. Any | 1843 | * cprm.limit of 0 here as a speacial value. Any |
1841 | * non-zero limit gets set to RLIM_INFINITY below, but | 1844 | * non-zero limit gets set to RLIM_INFINITY below, but |
1842 | * a limit of 0 skips the dump. This is a consistent | 1845 | * a limit of 0 skips the dump. This is a consistent |
1843 | * way to catch recursive crashes. We can still crash | 1846 | * way to catch recursive crashes. We can still crash |
@@ -1870,25 +1873,25 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1870 | goto fail_dropcount; | 1873 | goto fail_dropcount; |
1871 | } | 1874 | } |
1872 | 1875 | ||
1873 | core_limit = RLIM_INFINITY; | 1876 | cprm.limit = RLIM_INFINITY; |
1874 | 1877 | ||
1875 | /* SIGPIPE can happen, but it's just never processed */ | 1878 | /* SIGPIPE can happen, but it's just never processed */ |
1876 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, | 1879 | if (call_usermodehelper_pipe(helper_argv[0], helper_argv, NULL, |
1877 | &file)) { | 1880 | &cprm.file)) { |
1878 | printk(KERN_INFO "Core dump to %s pipe failed\n", | 1881 | printk(KERN_INFO "Core dump to %s pipe failed\n", |
1879 | corename); | 1882 | corename); |
1880 | goto fail_dropcount; | 1883 | goto fail_dropcount; |
1881 | } | 1884 | } |
1882 | } else | 1885 | } else |
1883 | file = filp_open(corename, | 1886 | cprm.file = filp_open(corename, |
1884 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, | 1887 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1885 | 0600); | 1888 | 0600); |
1886 | if (IS_ERR(file)) | 1889 | if (IS_ERR(cprm.file)) |
1887 | goto fail_dropcount; | 1890 | goto fail_dropcount; |
1888 | inode = file->f_path.dentry->d_inode; | 1891 | inode = cprm.file->f_path.dentry->d_inode; |
1889 | if (inode->i_nlink > 1) | 1892 | if (inode->i_nlink > 1) |
1890 | goto close_fail; /* multiple links - don't dump */ | 1893 | goto close_fail; /* multiple links - don't dump */ |
1891 | if (!ispipe && d_unhashed(file->f_path.dentry)) | 1894 | if (!ispipe && d_unhashed(cprm.file->f_path.dentry)) |
1892 | goto close_fail; | 1895 | goto close_fail; |
1893 | 1896 | ||
1894 | /* AK: actually i see no reason to not allow this for named pipes etc., | 1897 | /* AK: actually i see no reason to not allow this for named pipes etc., |
@@ -1901,21 +1904,22 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1901 | */ | 1904 | */ |
1902 | if (inode->i_uid != current_fsuid()) | 1905 | if (inode->i_uid != current_fsuid()) |
1903 | goto close_fail; | 1906 | goto close_fail; |
1904 | if (!file->f_op) | 1907 | if (!cprm.file->f_op) |
1905 | goto close_fail; | 1908 | goto close_fail; |
1906 | if (!file->f_op->write) | 1909 | if (!cprm.file->f_op->write) |
1907 | goto close_fail; | 1910 | goto close_fail; |
1908 | if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) | 1911 | if (!ispipe && |
1912 | do_truncate(cprm.file->f_path.dentry, 0, 0, cprm.file) != 0) | ||
1909 | goto close_fail; | 1913 | goto close_fail; |
1910 | 1914 | ||
1911 | retval = binfmt->core_dump(signr, regs, file, core_limit); | 1915 | retval = binfmt->core_dump(&cprm); |
1912 | 1916 | ||
1913 | if (retval) | 1917 | if (retval) |
1914 | current->signal->group_exit_code |= 0x80; | 1918 | current->signal->group_exit_code |= 0x80; |
1915 | close_fail: | 1919 | close_fail: |
1916 | if (ispipe && core_pipe_limit) | 1920 | if (ispipe && core_pipe_limit) |
1917 | wait_for_dump_helpers(file); | 1921 | wait_for_dump_helpers(cprm.file); |
1918 | filp_close(file, NULL); | 1922 | filp_close(cprm.file, NULL); |
1919 | fail_dropcount: | 1923 | fail_dropcount: |
1920 | if (dump_count) | 1924 | if (dump_count) |
1921 | atomic_dec(&core_dump_count); | 1925 | atomic_dec(&core_dump_count); |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index aece486ac734..cd4349bdc34e 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h | |||
@@ -68,6 +68,14 @@ struct linux_binprm{ | |||
68 | 68 | ||
69 | #define BINPRM_MAX_RECURSION 4 | 69 | #define BINPRM_MAX_RECURSION 4 |
70 | 70 | ||
71 | /* Function parameter for binfmt->coredump */ | ||
72 | struct coredump_params { | ||
73 | long signr; | ||
74 | struct pt_regs *regs; | ||
75 | struct file *file; | ||
76 | unsigned long limit; | ||
77 | }; | ||
78 | |||
71 | /* | 79 | /* |
72 | * This structure defines the functions that are used to load the binary formats that | 80 | * This structure defines the functions that are used to load the binary formats that |
73 | * linux accepts. | 81 | * linux accepts. |
@@ -77,7 +85,7 @@ struct linux_binfmt { | |||
77 | struct module *module; | 85 | struct module *module; |
78 | int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); | 86 | int (*load_binary)(struct linux_binprm *, struct pt_regs * regs); |
79 | int (*load_shlib)(struct file *); | 87 | int (*load_shlib)(struct file *); |
80 | int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); | 88 | int (*core_dump)(struct coredump_params *cprm); |
81 | unsigned long min_coredump; /* minimal dump size */ | 89 | unsigned long min_coredump; /* minimal dump size */ |
82 | int hasvdso; | 90 | int hasvdso; |
83 | }; | 91 | }; |