All of lore.kernel.org
 help / color / mirror / Atom feed
From: Corey Minyard <minyard@acm.org>
To: lkml <linux-kernel@vger.kernel.org>
Subject: Possible race between multi-threaded coredumps and fork
Date: Thu, 03 Jun 2004 10:00:39 -0500	[thread overview]
Message-ID: <40BF3D17.8030504@acm.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 783 bytes --]

A customer had a field problem with multi-threaded coredumps,
and I think the fix is the exit race (already fixed in 2.6), but I
also noticed a possible race between taking a coredump and fork().

If zap_threads() in fs/exec.c is called while a thread is in do_fork(),
but before the newly created thread is in the thread list, it is possible
to have a running thread during the coredump.  This is bad, but not
terribly bad.  However, in this situation it is also possible in
__exit_mm() that the final two threads check mm->core_waiters at
the same time and then both decrement mm->core_waiters, causing
it to go negative, and thus causing a BUG() in coredump_wait().

To fix this, I would like to propose the attached patch to 2.6.

Signed-off-by: Corey Minyard <minyard@acm.org>


[-- Attachment #2: coredump-fork-race.diff --]
[-- Type: text/plain, Size: 1411 bytes --]

--- linux.orig/kernel/fork.c	2004-05-21 11:49:07.000000000 -0500
+++ linux/kernel/fork.c	2004-06-03 09:46:00.000000000 -0500
@@ -1011,6 +1011,9 @@
 	INIT_LIST_HEAD(&p->ptrace_children);
 	INIT_LIST_HEAD(&p->ptrace_list);
 
+	/* Need the mmap_sem lock for coredump synchronization. */
+	if (p->mm)
+		down_read(&p->mm->mmap_sem);
 	/* Need tasklist lock for parent etc handling! */
 	write_lock_irq(&tasklist_lock);
 	/*
@@ -1019,6 +1022,7 @@
 	 */
 	if (sigismember(&current->pending.signal, SIGKILL)) {
 		write_unlock_irq(&tasklist_lock);
+		up_read(&p->mm->mmap_sem);
 		retval = -EINTR;
 		goto bad_fork_cleanup_namespace;
 	}
@@ -1040,6 +1044,7 @@
 		if (current->signal->group_exit) {
 			spin_unlock(&current->sighand->siglock);
 			write_unlock_irq(&tasklist_lock);
+			up_read(&p->mm->mmap_sem);
 			retval = -EAGAIN;
 			goto bad_fork_cleanup_namespace;
 		}
@@ -1075,6 +1080,23 @@
 
 	nr_threads++;
 	write_unlock_irq(&tasklist_lock);
+
+	if (p->mm) {
+		if (p->mm->core_waiters) {
+			/*
+			 * The thread group I am in is currently
+			 * taking a coredump so add the new thread as
+			 * a coredump candidate force the new thread
+			 * to die immediately.
+			 */
+			up_read(&p->mm->mmap_sem);
+			down_write(&p->mm->mmap_sem);
+			force_sig_specific(SIGKILL, p);
+			p->mm->core_waiters++;
+			up_write(&p->mm->mmap_sem);
+		} else
+			up_read(&p->mm->mmap_sem);
+	}
 	retval = 0;
 
 fork_out:

                 reply	other threads:[~2004-06-03 15:09 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40BF3D17.8030504@acm.org \
    --to=minyard@acm.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.