Commit 7dc0b22e3c54f1f4730354fef84a20f5944f6c5e

Authored by Neil Horman
Committed by Linus Torvalds
1 parent 8e2b705649

core_pattern: ignore RLIMIT_CORE if core_pattern is a pipe

For some time /proc/sys/kernel/core_pattern has been able to set its output
destination as a pipe, allowing a user space helper to receive and
intellegently process a core.  This infrastructure however has some
shortcommings which can be enhanced.  Specifically:

1) The coredump code in the kernel should ignore RLIMIT_CORE limitation
   when core_pattern is a pipe, since file system resources are not being
   consumed in this case, unless the user application wishes to save the core,
   at which point the app is restricted by usual file system limits and
   restrictions.

2) The core_pattern code should be able to parse and pass options to the
   user space helper as an argv array.  The real core limit of the uid of the
   crashing proces should also be passable to the user space helper (since it
   is overridden to zero when called).

3) Some miscellaneous bugs need to be cleaned up (specifically the
   recognition of a recursive core dump, should the user mode helper itself
   crash.  Also, the core dump code in the kernel should not wait for the user
   mode helper to exit, since the same context is responsible for writing to
   the pipe, and a read of the pipe by the user mode helper will result in a
   deadlock.

This patch:

Remove the check of RLIMIT_CORE if core_pattern is a pipe.  In the event that
core_pattern is a pipe, the entire core will be fed to the user mode helper.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Cc: <martin.pitt@ubuntu.com>
Cc: <wwoods@redhat.com>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 10 changed files with 39 additions and 39 deletions Side-by-side Diff

arch/mips/kernel/irixelf.c
... ... @@ -44,7 +44,7 @@
44 44 static int load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs);
45 45 static int load_irix_library(struct file *);
46 46 static int irix_core_dump(long signr, struct pt_regs * regs,
47   - struct file *file);
  47 + struct file *file, unsigned long limit);
48 48  
49 49 static struct linux_binfmt irix_format = {
50 50 .module = THIS_MODULE,
... ... @@ -1091,7 +1091,7 @@
1091 1091 * and then they are actually written out. If we run out of core limit
1092 1092 * we just truncate.
1093 1093 */
1094   -static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
  1094 +static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
1095 1095 {
1096 1096 int has_dumped = 0;
1097 1097 mm_segment_t fs;
... ... @@ -1101,7 +1101,6 @@
1101 1101 struct vm_area_struct *vma;
1102 1102 struct elfhdr elf;
1103 1103 off_t offset = 0, dataoff;
1104   - int limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
1105 1104 int numnote = 3;
1106 1105 struct memelfnote notes[3];
1107 1106 struct elf_prstatus prstatus; /* NT_PRSTATUS */
arch/sparc64/kernel/binfmt_aout32.c
... ... @@ -35,7 +35,7 @@
35 35  
36 36 static int load_aout32_binary(struct linux_binprm *, struct pt_regs * regs);
37 37 static int load_aout32_library(struct file*);
38   -static int aout32_core_dump(long signr, struct pt_regs * regs, struct file *file);
  38 +static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
39 39  
40 40 static struct linux_binfmt aout32_format = {
41 41 .module = THIS_MODULE,
... ... @@ -86,7 +86,7 @@
86 86 * dumping of the process results in another error..
87 87 */
88 88  
89   -static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file)
  89 +static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
90 90 {
91 91 mm_segment_t fs;
92 92 int has_dumped = 0;
93 93  
... ... @@ -105,13 +105,11 @@
105 105  
106 106 /* If the size of the dump file exceeds the rlimit, then see what would happen
107 107 if we wrote the stack, but not the data area. */
108   - if ((dump.u_dsize+dump.u_ssize) >
109   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  108 + if (dump.u_dsize + dump.u_ssize > limit)
110 109 dump.u_dsize = 0;
111 110  
112 111 /* Make sure we have enough room to write the stack and data areas. */
113   - if ((dump.u_ssize) >
114   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  112 + if (dump.u_ssize > limit)
115 113 dump.u_ssize = 0;
116 114  
117 115 /* make sure we actually have a data and stack area to dump */
arch/x86/ia32/ia32_aout.c
... ... @@ -40,7 +40,7 @@
40 40 static int load_aout_library(struct file*);
41 41  
42 42 #ifdef CORE_DUMP
43   -static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
  43 +static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
44 44  
45 45 /*
46 46 * fill in the user structure for a core dump..
... ... @@ -148,7 +148,7 @@
148 148 * dumping of the process results in another error..
149 149 */
150 150  
151   -static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
  151 +static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
152 152 {
153 153 mm_segment_t fs;
154 154 int has_dumped = 0;
155 155  
... ... @@ -168,13 +168,11 @@
168 168  
169 169 /* If the size of the dump file exceeds the rlimit, then see what would happen
170 170 if we wrote the stack, but not the data area. */
171   - if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
172   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  171 + if ((dump.u_dsize + dump.u_ssize + 1) * PAGE_SIZE > limit)
173 172 dump.u_dsize = 0;
174 173  
175 174 /* Make sure we have enough room to write the stack and data areas. */
176   - if ((dump.u_ssize+1) * PAGE_SIZE >
177   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  175 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
178 176 dump.u_ssize = 0;
179 177  
180 178 /* make sure we actually have a data and stack area to dump */
... ... @@ -31,7 +31,7 @@
31 31  
32 32 static int load_aout_binary(struct linux_binprm *, struct pt_regs * regs);
33 33 static int load_aout_library(struct file*);
34   -static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file);
  34 +static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
35 35  
36 36 static struct linux_binfmt aout_format = {
37 37 .module = THIS_MODULE,
... ... @@ -88,7 +88,7 @@
88 88 * dumping of the process results in another error..
89 89 */
90 90  
91   -static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
  91 +static int aout_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
92 92 {
93 93 mm_segment_t fs;
94 94 int has_dumped = 0;
95 95  
96 96  
97 97  
... ... @@ -123,23 +123,19 @@
123 123 /* If the size of the dump file exceeds the rlimit, then see what would happen
124 124 if we wrote the stack, but not the data area. */
125 125 #ifdef __sparc__
126   - if ((dump.u_dsize+dump.u_ssize) >
127   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  126 + if ((dump.u_dsize + dump.u_ssize) > limit)
128 127 dump.u_dsize = 0;
129 128 #else
130   - if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
131   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  129 + if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
132 130 dump.u_dsize = 0;
133 131 #endif
134 132  
135 133 /* Make sure we have enough room to write the stack and data areas. */
136 134 #ifdef __sparc__
137   - if ((dump.u_ssize) >
138   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  135 + if (dump.u_ssize > limit)
139 136 dump.u_ssize = 0;
140 137 #else
141   - if ((dump.u_ssize+1) * PAGE_SIZE >
142   - current->signal->rlim[RLIMIT_CORE].rlim_cur)
  138 + if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
143 139 dump.u_ssize = 0;
144 140 #endif
145 141  
... ... @@ -52,7 +52,7 @@
52 52 * don't even try.
53 53 */
54 54 #if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
55   -static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file);
  55 +static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
56 56 #else
57 57 #define elf_core_dump NULL
58 58 #endif
... ... @@ -1488,7 +1488,7 @@
1488 1488 * and then they are actually written out. If we run out of core limit
1489 1489 * we just truncate.
1490 1490 */
1491   -static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
  1491 +static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
1492 1492 {
1493 1493 #define NUM_NOTES 6
1494 1494 int has_dumped = 0;
... ... @@ -1499,7 +1499,6 @@
1499 1499 struct vm_area_struct *vma, *gate_vma;
1500 1500 struct elfhdr *elf = NULL;
1501 1501 loff_t offset = 0, dataoff, foffset;
1502   - unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
1503 1502 int numnote;
1504 1503 struct memelfnote *notes = NULL;
1505 1504 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
fs/binfmt_elf_fdpic.c
... ... @@ -75,7 +75,7 @@
75 75 struct file *, struct mm_struct *);
76 76  
77 77 #if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
78   -static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *);
  78 +static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *, unsigned long limit);
79 79 #endif
80 80  
81 81 static struct linux_binfmt elf_fdpic_format = {
... ... @@ -1552,7 +1552,7 @@
1552 1552 * we just truncate.
1553 1553 */
1554 1554 static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1555   - struct file *file)
  1555 + struct file *file, unsigned long limit)
1556 1556 {
1557 1557 #define NUM_NOTES 6
1558 1558 int has_dumped = 0;
... ... @@ -1563,7 +1563,6 @@
1563 1563 struct vm_area_struct *vma;
1564 1564 struct elfhdr *elf = NULL;
1565 1565 loff_t offset = 0, dataoff;
1566   - unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
1567 1566 int numnote;
1568 1567 struct memelfnote *notes = NULL;
1569 1568 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
... ... @@ -75,7 +75,7 @@
75 75 #endif
76 76  
77 77 static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs);
78   -static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file);
  78 +static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
79 79  
80 80 static struct linux_binfmt flat_format = {
81 81 .module = THIS_MODULE,
... ... @@ -90,7 +90,7 @@
90 90 * Currently only a stub-function.
91 91 */
92 92  
93   -static int flat_core_dump(long signr, struct pt_regs * regs, struct file *file)
  93 +static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
94 94 {
95 95 printk("Process %s:%d received signr %d and should have core dumped\n",
96 96 current->comm, current->pid, (int) signr);
... ... @@ -44,7 +44,7 @@
44 44 * don't even try.
45 45 */
46 46 #if 0
47   -static int som_core_dump(long signr, struct pt_regs * regs);
  47 +static int som_core_dump(long signr, struct pt_regs *regs, unsigned long limit);
48 48 #else
49 49 #define som_core_dump NULL
50 50 #endif
... ... @@ -1697,6 +1697,7 @@
1697 1697 int fsuid = current->fsuid;
1698 1698 int flag = 0;
1699 1699 int ispipe = 0;
  1700 + unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
1700 1701  
1701 1702 audit_core_dumps(signr);
1702 1703  
... ... @@ -1730,9 +1731,6 @@
1730 1731 */
1731 1732 clear_thread_flag(TIF_SIGPENDING);
1732 1733  
1733   - if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
1734   - goto fail_unlock;
1735   -
1736 1734 /*
1737 1735 * lock_kernel() because format_corename() is controlled by sysctl, which
1738 1736 * uses lock_kernel()
1739 1737  
... ... @@ -1740,7 +1738,20 @@
1740 1738 lock_kernel();
1741 1739 ispipe = format_corename(corename, core_pattern, signr);
1742 1740 unlock_kernel();
  1741 + /*
  1742 + * Don't bother to check the RLIMIT_CORE value if core_pattern points
  1743 + * to a pipe. Since we're not writing directly to the filesystem
  1744 + * RLIMIT_CORE doesn't really apply, as no actual core file will be
  1745 + * created unless the pipe reader choses to write out the core file
  1746 + * at which point file size limits and permissions will be imposed
  1747 + * as it does with any other process
  1748 + */
  1749 + if ((!ispipe) &&
  1750 + (core_limit < binfmt->min_coredump))
  1751 + goto fail_unlock;
  1752 +
1743 1753 if (ispipe) {
  1754 + core_limit = RLIM_INFINITY;
1744 1755 /* SIGPIPE can happen, but it's just never processed */
1745 1756 if(call_usermodehelper_pipe(corename+1, NULL, NULL, &file)) {
1746 1757 printk(KERN_INFO "Core dump to %s pipe failed\n",
... ... @@ -1770,7 +1781,7 @@
1770 1781 if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0)
1771 1782 goto close_fail;
1772 1783  
1773   - retval = binfmt->core_dump(signr, regs, file);
  1784 + retval = binfmt->core_dump(signr, regs, file, core_limit);
1774 1785  
1775 1786 if (retval)
1776 1787 current->signal->group_exit_code |= 0x80;
include/linux/binfmts.h
... ... @@ -67,7 +67,7 @@
67 67 struct module *module;
68 68 int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
69 69 int (*load_shlib)(struct file *);
70   - int (*core_dump)(long signr, struct pt_regs * regs, struct file * file);
  70 + int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
71 71 unsigned long min_coredump; /* minimal dump size */
72 72 int hasvdso;
73 73 };