mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [BUG] 2.6.22-rc4: wait4() waiting for SIGSTOP may not return if the target process is ptraced
@ 2007-06-07  9:42 Satoru Takeuchi
  2007-06-07  9:54 ` Roland McGrath
  0 siblings, 1 reply; 4+ messages in thread
From: Satoru Takeuchi @ 2007-06-07  9:42 UTC (permalink / raw)
  To: Linux Kernel, Linus Torvalds, Andrew Morton, Oleg Nesterov,
	Roland McGrath
  Cc: Satoru Takeuchi

Hi,

I found a bug on signal code. wait4() after sending SIGSTOP may not return if
the target process is ptraced. It's caused by signal redirection mechainism.
Because of the bug, sometimes strace can't detach target process correctly.

I confirmed the following kernel have this bug.

  - i386 2.6.22-rc3
  - i386 2.6.22-rc4
  - ia64 2.6.22-rc3
  - ia64 2.6.22-rc4


Assuming that there are following processes:

 - P1:     a multi thread process. It consists of thread T1 and thread T2.
 - strace: attaching P1 with -f option

When you try to kill strace by signal, strace does the following for each
thread of P1. I regard T1 as the target thread in the following process.

  1. call ptrace(PTRACE_DETACH) to detach T1. It only succeed if the T1
     already traced or stopped. If succeed, no more work is needed for the
     thread.
  2. Send SIGSTOP to the T1.
  3. call wait4() to wait for the target thread's status change.
  4. call ptrace(PTRACE_DETACH) again. It succeed because T1 is stopped.

If the target thread is TASK_RUNNING on process 1, and is TASK_TRACED on
process 2, T2 receives SIGSTOP instead of T1. Then T2 try to wake up strace
on receiving SIGSTOP, but strace is waiting for T1, so strace can't wake
up eternally. In addition, traced process can't restart after that.

I have some ideas to fix this problem. How should I do?


  1. Fix __group_complete_signal()

     Don't redirect SIGSTOP to other thread.

  2. Fix do_notify_parent_cldstop()

     use the pid of original target thread for __wake_up_parent

  3. Fix wait4()

     Wait for tgid instead of pid.

  4. Bypass the problem (or other porcesses using above rendezvous)

     Change user land program such as strace to bypass this problem.

  5. others

     Does anyone know the better solution?


I attached the recreate program as usual.

Thanks,

Satoru

-------------------------------------------------------------------------------
/*
 * recreate-ptrace-mt-wait-for-sigstop - recreate a signal bug
 *
 * ---------------------------------------------------------------------------
 * 
 * Problem
 * =======
 *
 * wait4() after sending SIGSTOP may not return if the target process is
 * ptraced.
 *
 * 
 * Assuming that there are following processes:
 *
 *   - P1:     a multi thread process. It consists of thread T1 and thread T2.
 *   - strace: attaching P1 with -f option
 *
 * When you try to kill strace by signal, strace does the following for each
 * thread of P1. I regard T1 as the target thread in the following process.
 *
 *    1. call ptrace(PTRACE_DETACH) to detach T1. It only succeed if the T1
 *       already traced or stopped. If succeed, no more work is needed for
 *       the thread.
 *    2. Send SIGSTOP to the T1.
 *    3. call wait4() to wait for the target thread's status change.
 *    4. call ptrace(PTRACE_DETACH) again. It succeed because T1 is stopped.
 *
 * If the target thread is TASK_RUNNING on process 1, and is TASK_TRACED on
 * process 2, T2 recives SIGSTOP instead of T1. Then T2 try to wake up strace
 * on receiving SIGSTOP, but strace is waiting for T1, so strace can't wake
 * up eternally. In addition, traced process can't restart after that.
 *
 * How to recreate
 * ===============
 *
 * 1. run this program
 * 
 *    $ recreate-ptrace-mt-wait-for-sigstop &
 * 
 * 2. run strace and attach this program
 *
 *    $ strace -f -p $!
 *
 * 3. C-c on your terminal
 *
 * Expected Result
 * ===============
 *
 * All threads of this program was detached safely
 * 
 * Actual Result
 * =============
 *
 * strace sleeps on wait4() eternally.
 *
 * Note
 * ====
 *
 * This program can't always recreate a problem. However recreate
 * possibility is very high.
 * 
 *----------------------------------------------------------------------
 * 
 * Copyright 2007 Satoru Takeuchi <takeuchi_satoru@jp.futjisu.com>
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 * 
 */

#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>

void *thread_fn(void *arg)
{
	int i;

	for (;;) 
		sleep(1);
}

#define NTHREAD 64

int main(int argc, char **argv)
{
	pthread_t t[NTHREAD];
	int i;

	for (i = 0; i < NTHREAD; i++)
		if (pthread_create(&t[i], NULL, thread_fn, NULL)) {
			fprintf(stderr, "pthread_create(%d) failed\n", i);
			exit(EXIT_FAILURE);
		}

	thread_fn(NULL);

	for (i = 0; i < NTHREAD; i++)
		if (pthread_join(t[i], NULL))
			warn("pthread_join(%d) failed", i);

	exit(EXIT_SUCCESS);		    
}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [BUG] 2.6.22-rc4: wait4() waiting for SIGSTOP may not return if the target process is ptraced
  2007-06-07  9:42 [BUG] 2.6.22-rc4: wait4() waiting for SIGSTOP may not return if the target process is ptraced Satoru Takeuchi
@ 2007-06-07  9:54 ` Roland McGrath
  2007-06-07 10:15   ` Satoru Takeuchi
  0 siblings, 1 reply; 4+ messages in thread
From: Roland McGrath @ 2007-06-07  9:54 UTC (permalink / raw)
  To: Satoru Takeuchi
  Cc: Linux Kernel, Linus Torvalds, Andrew Morton, Oleg Nesterov

The bug is in strace (and is being fixed).  It needs to use tgkill instead
of kill to send that SIGSTOP to the right thread only.  


Thanks,
Roland

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [BUG] 2.6.22-rc4: wait4() waiting for SIGSTOP may not return if the target process is ptraced
  2007-06-07  9:54 ` Roland McGrath
@ 2007-06-07 10:15   ` Satoru Takeuchi
  2007-06-13 20:20     ` Roland McGrath
  0 siblings, 1 reply; 4+ messages in thread
From: Satoru Takeuchi @ 2007-06-07 10:15 UTC (permalink / raw)
  To: Roland McGrath
  Cc: Satoru Takeuchi, Linux Kernel, Linus Torvalds, Andrew Morton,
	Oleg Nesterov

Hi,

At Thu,  7 Jun 2007 02:54:32 -0700 (PDT),
Roland McGrath wrote:
> 
> The bug is in strace (and is being fixed).  It needs to use tgkill instead
> of kill to send that SIGSTOP to the right thread only.  

You mean kill() to specifig thread is fundamentally wrong? If so, current
kill() is wrong because it can receive pid of non main thread.

Thanks,

Satoru

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [BUG] 2.6.22-rc4: wait4() waiting for SIGSTOP may not return if the target process is ptraced
  2007-06-07 10:15   ` Satoru Takeuchi
@ 2007-06-13 20:20     ` Roland McGrath
  0 siblings, 0 replies; 4+ messages in thread
From: Roland McGrath @ 2007-06-13 20:20 UTC (permalink / raw)
  To: Satoru Takeuchi
  Cc: Linux Kernel, Linus Torvalds, Andrew Morton, Oleg Nesterov

> > The bug is in strace (and is being fixed).  It needs to use tgkill instead
> > of kill to send that SIGSTOP to the right thread only.  
> 
> You mean kill() to specifig thread is fundamentally wrong? If so, current
> kill() is wrong because it can receive pid of non main thread.

The kill call should only be used on process IDs (tgid in linuspeak).  This
is what POSIX defines it for.  I'm not sure off hand if it's technically a
violation of POSIX that it works for numbers that aren't a POSIX process ID
(aka tgid) but happen happen to be a Linux thread ID (aka pid).


Thanks,
Roland

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-06-13 20:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-07  9:42 [BUG] 2.6.22-rc4: wait4() waiting for SIGSTOP may not return if the target process is ptraced Satoru Takeuchi
2007-06-07  9:54 ` Roland McGrath
2007-06-07 10:15   ` Satoru Takeuchi
2007-06-13 20:20     ` Roland McGrath

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®