aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exec.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2010-03-05 16:44:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-06 14:26:46 -0500
commit30736a4d43f4af7f1a7836d6a266be17082195c4 (patch)
tree54e388cdaf4795bdb7651be03c50bba67eb0b43a /fs/exec.c
parent8d9032bbe4671dc481261ccd4e161cd96e54b118 (diff)
coredump: pass mm->flags as a coredump parameter for consistency
Pass mm->flags as a coredump parameter for consistency. --- 1787 if (mm->core_state || !get_dumpable(mm)) { <- (1) 1788 up_write(&mm->mmap_sem); 1789 put_cred(cred); 1790 goto fail; 1791 } 1792 [...] 1798 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ <-(2) 1799 flag = O_EXCL; /* Stop rewrite attacks */ 1800 cred->fsuid = 0; /* Dump root private */ 1801 } --- Since dumpable bits are not protected by lock, there is a chance to change these bits between (1) and (2). To solve this issue, this patch copies mm->flags to coredump_params.mm_flags at the beginning of do_coredump() and uses it instead of get_dumpable() while dumping core. This copy is also passed to binfmt->core_dump, since elf*_core_dump() uses dump_filter bits in mm->flags. [akpm@linux-foundation.org: fix merge] Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Acked-by: Roland McGrath <roland@redhat.com> Cc: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Reviewed-by: 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>
Diffstat (limited to 'fs/exec.c')
-rw-r--r--fs/exec.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/exec.c b/fs/exec.c
index da2b31dc4e1c..89d4080c1435 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1748,14 +1748,19 @@ void set_dumpable(struct mm_struct *mm, int value)
1748 } 1748 }
1749} 1749}
1750 1750
1751int get_dumpable(struct mm_struct *mm) 1751static int __get_dumpable(unsigned long mm_flags)
1752{ 1752{
1753 int ret; 1753 int ret;
1754 1754
1755 ret = mm->flags & 0x3; 1755 ret = mm_flags & MMF_DUMPABLE_MASK;
1756 return (ret >= 2) ? 2 : ret; 1756 return (ret >= 2) ? 2 : ret;
1757} 1757}
1758 1758
1759int get_dumpable(struct mm_struct *mm)
1760{
1761 return __get_dumpable(mm->flags);
1762}
1763
1759static void wait_for_dump_helpers(struct file *file) 1764static void wait_for_dump_helpers(struct file *file)
1760{ 1765{
1761 struct pipe_inode_info *pipe; 1766 struct pipe_inode_info *pipe;
@@ -1799,6 +1804,12 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1799 .signr = signr, 1804 .signr = signr,
1800 .regs = regs, 1805 .regs = regs,
1801 .limit = rlimit(RLIMIT_CORE), 1806 .limit = rlimit(RLIMIT_CORE),
1807 /*
1808 * We must use the same mm->flags while dumping core to avoid
1809 * inconsistency of bit flags, since this flag is not protected
1810 * by any locks.
1811 */
1812 .mm_flags = mm->flags,
1802 }; 1813 };
1803 1814
1804 audit_core_dumps(signr); 1815 audit_core_dumps(signr);
@@ -1817,7 +1828,7 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1817 /* 1828 /*
1818 * If another thread got here first, or we are not dumpable, bail out. 1829 * If another thread got here first, or we are not dumpable, bail out.
1819 */ 1830 */
1820 if (mm->core_state || !get_dumpable(mm)) { 1831 if (mm->core_state || !__get_dumpable(cprm.mm_flags)) {
1821 up_write(&mm->mmap_sem); 1832 up_write(&mm->mmap_sem);
1822 put_cred(cred); 1833 put_cred(cred);
1823 goto fail; 1834 goto fail;
@@ -1828,7 +1839,8 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs)
1828 * process nor do we know its entire history. We only know it 1839 * process nor do we know its entire history. We only know it
1829 * was tainted so we dump it as root in mode 2. 1840 * was tainted so we dump it as root in mode 2.
1830 */ 1841 */
1831 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ 1842 if (__get_dumpable(cprm.mm_flags) == 2) {
1843 /* Setuid core dump mode */
1832 flag = O_EXCL; /* Stop rewrite attacks */ 1844 flag = O_EXCL; /* Stop rewrite attacks */
1833 cred->fsuid = 0; /* Dump root private */ 1845 cred->fsuid = 0; /* Dump root private */
1834 } 1846 }