diff options
author | Michal Hocko <mhocko@suse.com> | 2016-09-01 19:15:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-01 20:52:02 -0400 |
commit | 735f2770a770156100f534646158cb58cb8b2939 (patch) | |
tree | 9dfd8a804c9f59ce2bea291eeb9f0d13c676a6c0 /kernel/fork.c | |
parent | c4e297386bd1621b83f6f7d58a729fb770597a91 (diff) |
kernel/fork: fix CLONE_CHILD_CLEARTID regression in nscd
Commit fec1d0115240 ("[PATCH] Disable CLONE_CHILD_CLEARTID for abnormal
exit") has caused a subtle regression in nscd which uses
CLONE_CHILD_CLEARTID to clear the nscd_certainly_running flag in the
shared databases, so that the clients are notified when nscd is
restarted. Now, when nscd uses a non-persistent database, clients that
have it mapped keep thinking the database is being updated by nscd, when
in fact nscd has created a new (anonymous) one (for non-persistent
databases it uses an unlinked file as backend).
The original proposal for the CLONE_CHILD_CLEARTID change claimed
(https://lkml.org/lkml/2006/10/25/233):
: The NPTL library uses the CLONE_CHILD_CLEARTID flag on clone() syscalls
: on behalf of pthread_create() library calls. This feature is used to
: request that the kernel clear the thread-id in user space (at an address
: provided in the syscall) when the thread disassociates itself from the
: address space, which is done in mm_release().
:
: Unfortunately, when a multi-threaded process incurs a core dump (such as
: from a SIGSEGV), the core-dumping thread sends SIGKILL signals to all of
: the other threads, which then proceed to clear their user-space tids
: before synchronizing in exit_mm() with the start of core dumping. This
: misrepresents the state of process's address space at the time of the
: SIGSEGV and makes it more difficult for someone to debug NPTL and glibc
: problems (misleading him/her to conclude that the threads had gone away
: before the fault).
:
: The fix below is to simply avoid the CLONE_CHILD_CLEARTID action if a
: core dump has been initiated.
The resulting patch from Roland (https://lkml.org/lkml/2006/10/26/269)
seems to have a larger scope than the original patch asked for. It
seems that limitting the scope of the check to core dumping should work
for SIGSEGV issue describe above.
[Changelog partly based on Andreas' description]
Fixes: fec1d0115240 ("[PATCH] Disable CLONE_CHILD_CLEARTID for abnormal exit")
Link: http://lkml.kernel.org/r/1471968749-26173-1-git-send-email-mhocko@kernel.org
Signed-off-by: Michal Hocko <mhocko@suse.com>
Tested-by: William Preston <wpreston@suse.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Cc: Roland McGrath <roland@hack.frob.com>
Cc: Andreas Schwab <schwab@suse.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index aaf782327bf3..93bdba13d7d9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -913,14 +913,12 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
913 | deactivate_mm(tsk, mm); | 913 | deactivate_mm(tsk, mm); |
914 | 914 | ||
915 | /* | 915 | /* |
916 | * If we're exiting normally, clear a user-space tid field if | 916 | * Signal userspace if we're not exiting with a core dump |
917 | * requested. We leave this alone when dying by signal, to leave | 917 | * because we want to leave the value intact for debugging |
918 | * the value intact in a core dump, and to save the unnecessary | 918 | * purposes. |
919 | * trouble, say, a killed vfork parent shouldn't touch this mm. | ||
920 | * Userland only wants this done for a sys_exit. | ||
921 | */ | 919 | */ |
922 | if (tsk->clear_child_tid) { | 920 | if (tsk->clear_child_tid) { |
923 | if (!(tsk->flags & PF_SIGNALED) && | 921 | if (!(tsk->signal->flags & SIGNAL_GROUP_COREDUMP) && |
924 | atomic_read(&mm->mm_users) > 1) { | 922 | atomic_read(&mm->mm_users) > 1) { |
925 | /* | 923 | /* |
926 | * We don't check the error code - if userspace has | 924 | * We don't check the error code - if userspace has |