diff options
author | Oleg Nesterov <oleg@redhat.com> | 2010-05-26 17:43:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 12:12:45 -0400 |
commit | 269b005a28e124a341df4adef2c3661cf7371fcc (patch) | |
tree | 226b105cc4c1bbe0b3fe92f2733708a7dc2dedb8 /fs/exec.c | |
parent | 5e43aef530ba39206f7923295388f7ec3c5a7d93 (diff) |
coredump: shift down_write(mmap_sem) into coredump_wait()
- move the cprm.mm_flags checks up, before we take mmap_sem
- move down_write(mmap_sem) and ->core_state check from do_coredump()
to coredump_wait()
This simplifies the code and makes the locking symmetrical.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Neil Horman <nhorman@tuxdriver.com>
Cc: Roland McGrath <roland@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
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 | 19 |
1 files changed, 7 insertions, 12 deletions
@@ -1662,12 +1662,15 @@ static int coredump_wait(int exit_code, struct core_state *core_state) | |||
1662 | struct task_struct *tsk = current; | 1662 | struct task_struct *tsk = current; |
1663 | struct mm_struct *mm = tsk->mm; | 1663 | struct mm_struct *mm = tsk->mm; |
1664 | struct completion *vfork_done; | 1664 | struct completion *vfork_done; |
1665 | int core_waiters; | 1665 | int core_waiters = -EBUSY; |
1666 | 1666 | ||
1667 | init_completion(&core_state->startup); | 1667 | init_completion(&core_state->startup); |
1668 | core_state->dumper.task = tsk; | 1668 | core_state->dumper.task = tsk; |
1669 | core_state->dumper.next = NULL; | 1669 | core_state->dumper.next = NULL; |
1670 | core_waiters = zap_threads(tsk, mm, core_state, exit_code); | 1670 | |
1671 | down_write(&mm->mmap_sem); | ||
1672 | if (!mm->core_state) | ||
1673 | core_waiters = zap_threads(tsk, mm, core_state, exit_code); | ||
1671 | up_write(&mm->mmap_sem); | 1674 | up_write(&mm->mmap_sem); |
1672 | 1675 | ||
1673 | if (unlikely(core_waiters < 0)) | 1676 | if (unlikely(core_waiters < 0)) |
@@ -1860,20 +1863,12 @@ void do_coredump(long signr, int exit_code, struct pt_regs *regs) | |||
1860 | binfmt = mm->binfmt; | 1863 | binfmt = mm->binfmt; |
1861 | if (!binfmt || !binfmt->core_dump) | 1864 | if (!binfmt || !binfmt->core_dump) |
1862 | goto fail; | 1865 | goto fail; |
1866 | if (!__get_dumpable(cprm.mm_flags)) | ||
1867 | goto fail; | ||
1863 | 1868 | ||
1864 | cred = prepare_creds(); | 1869 | cred = prepare_creds(); |
1865 | if (!cred) | 1870 | if (!cred) |
1866 | goto fail; | 1871 | goto fail; |
1867 | |||
1868 | down_write(&mm->mmap_sem); | ||
1869 | /* | ||
1870 | * If another thread got here first, or we are not dumpable, bail out. | ||
1871 | */ | ||
1872 | if (mm->core_state || !__get_dumpable(cprm.mm_flags)) { | ||
1873 | up_write(&mm->mmap_sem); | ||
1874 | goto fail_creds; | ||
1875 | } | ||
1876 | |||
1877 | /* | 1872 | /* |
1878 | * We cannot trust fsuid as being the "true" uid of the | 1873 | * We cannot trust fsuid as being the "true" uid of the |
1879 | * process nor do we know its entire history. We only know it | 1874 | * process nor do we know its entire history. We only know it |