diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2010-03-05 16:44:12 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-06 14:26:46 -0500 |
commit | 30736a4d43f4af7f1a7836d6a266be17082195c4 (patch) | |
tree | 54e388cdaf4795bdb7651be03c50bba67eb0b43a /fs/exec.c | |
parent | 8d9032bbe4671dc481261ccd4e161cd96e54b118 (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.c | 20 |
1 files changed, 16 insertions, 4 deletions
@@ -1748,14 +1748,19 @@ void set_dumpable(struct mm_struct *mm, int value) | |||
1748 | } | 1748 | } |
1749 | } | 1749 | } |
1750 | 1750 | ||
1751 | int get_dumpable(struct mm_struct *mm) | 1751 | static 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 | ||
1759 | int get_dumpable(struct mm_struct *mm) | ||
1760 | { | ||
1761 | return __get_dumpable(mm->flags); | ||
1762 | } | ||
1763 | |||
1759 | static void wait_for_dump_helpers(struct file *file) | 1764 | static 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 | } |