Revision 4ab6c08336535f8c8e42cf45d7adeda882eff06e authored by Oleg Nesterov on 26 August 2009, 21:29:24 UTC, committed by Linus Torvalds on 27 August 2009, 03:06:52 UTC
Spotted by Hiroshi Shimamoto who also provided the test-case below.

copy_process() uses signal->count as a reference counter, but it is not.
This test case

	#include <sys/types.h>
	#include <sys/wait.h>
	#include <unistd.h>
	#include <stdio.h>
	#include <errno.h>
	#include <pthread.h>

	void *null_thread(void *p)
	{
		for (;;)
			sleep(1);

		return NULL;
	}

	void *exec_thread(void *p)
	{
		execl("/bin/true", "/bin/true", NULL);

		return null_thread(p);
	}

	int main(int argc, char **argv)
	{
		for (;;) {
			pid_t pid;
			int ret, status;

			pid = fork();
			if (pid < 0)
				break;

			if (!pid) {
				pthread_t tid;

				pthread_create(&tid, NULL, exec_thread, NULL);
				for (;;)
					pthread_create(&tid, NULL, null_thread, NULL);
			}

			do {
				ret = waitpid(pid, &status, 0);
			} while (ret == -1 && errno == EINTR);
		}

		return 0;
	}

quickly creates an unkillable task.

If copy_process(CLONE_THREAD) races with de_thread()
copy_signal()->atomic(signal->count) breaks the signal->notify_count
logic, and the execing thread can hang forever in kernel space.

Change copy_process() to increment count/live only when we know for sure
we can't fail.  In this case the forked thread will take care of its
reference to signal correctly.

If copy_process() fails, check CLONE_THREAD flag.  If it it set - do
nothing, the counters were not changed and current belongs to the same
thread group.  If it is not set, ->signal must be released in any case
(and ->count must be == 1), the forked child is the only thread in the
thread group.

We need more cleanups here, in particular signal->count should not be used
by de_thread/__exit_signal at all.  This patch only fixes the bug.

Reported-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Tested-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Roland McGrath <roland@redhat.com>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 03ef83a
History
File Mode Size
Kconfig -rw-r--r-- 2.5 KB
Kconfig.iosched -rw-r--r-- 1.9 KB
Makefile -rw-r--r-- 569 bytes
as-iosched.c -rw-r--r-- 38.7 KB
blk-barrier.c -rw-r--r-- 9.7 KB
blk-core.c -rw-r--r-- 63.8 KB
blk-exec.c -rw-r--r-- 2.6 KB
blk-integrity.c -rw-r--r-- 9.9 KB
blk-ioc.c -rw-r--r-- 4.0 KB
blk-map.c -rw-r--r-- 8.1 KB
blk-merge.c -rw-r--r-- 9.8 KB
blk-settings.c -rw-r--r-- 22.1 KB
blk-softirq.c -rw-r--r-- 4.1 KB
blk-sysfs.c -rw-r--r-- 11.7 KB
blk-tag.c -rw-r--r-- 9.9 KB
blk-timeout.c -rw-r--r-- 5.7 KB
blk.h -rw-r--r-- 4.5 KB
bsg.c -rw-r--r-- 23.4 KB
cfq-iosched.c -rw-r--r-- 63.9 KB
compat_ioctl.c -rw-r--r-- 21.6 KB
deadline-iosched.c -rw-r--r-- 11.4 KB
elevator.c -rw-r--r-- 24.9 KB
genhd.c -rw-r--r-- 29.1 KB
ioctl.c -rw-r--r-- 8.6 KB
noop-iosched.c -rw-r--r-- 2.6 KB
scsi_ioctl.c -rw-r--r-- 18.0 KB

back to top