Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2016-05-27 08:48:39 +0200
committerJiri Slaby <jslaby@suse.cz>2016-05-27 08:48:48 +0200
commitc847ff533678a2c6c34b9e324a0f103479809279 (patch)
tree4e442fce3a16006b7a8e360578c7c755b09872db
parent6b6f22b1563a61f3c12afa200a4093800e8ad9ef (diff)
- fork: free thread in copy_process on failure (bnc#968063).
- Update config files.
-rw-r--r--config/s390x/default1
-rw-r--r--config/s390x/zfcpdump1
-rw-r--r--config/x86_64/debug1
-rw-r--r--config/x86_64/default1
-rw-r--r--patches.fixes/0004-fork-free-thread-in-copy_process-on-failure.patch184
-rw-r--r--series.conf1
6 files changed, 189 insertions, 0 deletions
diff --git a/config/s390x/default b/config/s390x/default
index 94aee6d1e6..570b6af705 100644
--- a/config/s390x/default
+++ b/config/s390x/default
@@ -231,6 +231,7 @@ CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_HAVE_EXIT_THREAD=y
CONFIG_CLONE_BACKWARDS2=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y
diff --git a/config/s390x/zfcpdump b/config/s390x/zfcpdump
index 2f7df311b6..ca2818ca84 100644
--- a/config/s390x/zfcpdump
+++ b/config/s390x/zfcpdump
@@ -186,6 +186,7 @@ CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_HAVE_EXIT_THREAD=y
CONFIG_CLONE_BACKWARDS2=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OLD_SIGACTION=y
diff --git a/config/x86_64/debug b/config/x86_64/debug
index 9c74a66e4f..6bbdc5f868 100644
--- a/config/x86_64/debug
+++ b/config/x86_64/debug
@@ -303,6 +303,7 @@ CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_HAVE_EXIT_THREAD=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_COMPAT_OLD_SIGACTION=y
diff --git a/config/x86_64/default b/config/x86_64/default
index ad1c5c3f8d..da7c0cb99b 100644
--- a/config/x86_64/default
+++ b/config/x86_64/default
@@ -303,6 +303,7 @@ CONFIG_HAVE_ARCH_SOFT_DIRTY=y
CONFIG_MODULES_USE_ELF_RELA=y
CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
+CONFIG_HAVE_EXIT_THREAD=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_COMPAT_OLD_SIGACTION=y
diff --git a/patches.fixes/0004-fork-free-thread-in-copy_process-on-failure.patch b/patches.fixes/0004-fork-free-thread-in-copy_process-on-failure.patch
new file mode 100644
index 0000000000..82888aa4f8
--- /dev/null
+++ b/patches.fixes/0004-fork-free-thread-in-copy_process-on-failure.patch
@@ -0,0 +1,184 @@
+From: Jiri Slaby <jslaby@suse.cz>
+Date: Fri, 20 May 2016 17:00:25 -0700
+Subject: fork: free thread in copy_process on failure
+Git-commit: 0740aa5f6375681c57488c4ea55d05a0341cfc9c
+Patch-mainline: v4.7-rc1
+References: bnc#968063
+
+When using this program (as root):
+
+ #include <err.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ #include <sys/io.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+
+ #define ITER 1000
+ #define FORKERS 15
+ #define THREADS (6000/FORKERS) // 1850 is proc max
+
+ static void fork_100_wait()
+ {
+ unsigned a, to_wait = 0;
+
+ printf("\t%d forking %d\n", THREADS, getpid());
+
+ for (a = 0; a < THREADS; a++) {
+ switch (fork()) {
+ case 0:
+ usleep(1000);
+ exit(0);
+ break;
+ case -1:
+ break;
+ default:
+ to_wait++;
+ break;
+ }
+ }
+
+ printf("\t%d forked from %d, waiting for %d\n", THREADS, getpid(),
+ to_wait);
+
+ for (a = 0; a < to_wait; a++)
+ wait(NULL);
+
+ printf("\t%d waited from %d\n", THREADS, getpid());
+ }
+
+ static void run_forkers()
+ {
+ pid_t forkers[FORKERS];
+ unsigned a;
+
+ for (a = 0; a < FORKERS; a++) {
+ switch ((forkers[a] = fork())) {
+ case 0:
+ fork_100_wait();
+ exit(0);
+ break;
+ case -1:
+ err(1, "DIE fork of %d'th forker", a);
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (a = 0; a < FORKERS; a++)
+ waitpid(forkers[a], NULL, 0);
+ }
+
+ int main()
+ {
+ unsigned a;
+ int ret;
+
+ ret = ioperm(10, 20, 0);
+ if (ret < 0)
+ err(1, "ioperm");
+
+ for (a = 0; a < ITER; a++)
+ run_forkers();
+
+ return 0;
+ }
+
+kmemleak reports many occurences of this leak:
+unreferenced object 0xffff8805917c8000 (size 8192):
+ comm "fork-leak", pid 2932, jiffies 4295354292 (age 1871.028s)
+ hex dump (first 32 bytes):
+ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
+ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
+ backtrace:
+ [<ffffffff814cfbf5>] kmemdup+0x25/0x50
+ [<ffffffff8103ab43>] copy_thread_tls+0x6c3/0x9a0
+ [<ffffffff81150174>] copy_process+0x1a84/0x5790
+ [<ffffffff811dc375>] wake_up_new_task+0x2d5/0x6f0
+ [<ffffffff8115411d>] _do_fork+0x12d/0x820
+...
+
+Due to the leakage of the memory items which should have been freed in
+arch/x86/kernel/process.c:exit_thread().
+
+Make sure the memory is freed when fork fails later in copy_process.
+This is done by calling exit_thread with the thread to kill.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
+Cc: Aurelien Jacquiot <a-jacquiot@ti.com>
+Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Chen Liqin <liqin.linux@gmail.com>
+Cc: Chris Metcalf <cmetcalf@mellanox.com>
+Cc: Chris Zankel <chris@zankel.net>
+Cc: David Howells <dhowells@redhat.com>
+Cc: Fenghua Yu <fenghua.yu@intel.com>
+Cc: Geert Uytterhoeven <geert@linux-m68k.org>
+Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
+Cc: Haavard Skinnemoen <hskinnemoen@gmail.com>
+Cc: Hans-Christian Egtvedt <egtvedt@samfundet.no>
+Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
+Cc: Helge Deller <deller@gmx.de>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+Cc: James Hogan <james.hogan@imgtec.com>
+Cc: Jeff Dike <jdike@addtoit.com>
+Cc: Jesper Nilsson <jesper.nilsson@axis.com>
+Cc: Jiri Slaby <jslaby@suse.cz>
+Cc: Jonas Bonn <jonas@southpole.se>
+Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
+Cc: Lennox Wu <lennox.wu@gmail.com>
+Cc: Ley Foon Tan <lftan@altera.com>
+Cc: Mark Salter <msalter@redhat.com>
+Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Cc: Matt Turner <mattst88@gmail.com>
+Cc: Max Filippov <jcmvbkbc@gmail.com>
+Cc: Michael Ellerman <mpe@ellerman.id.au>
+Cc: Michal Simek <monstr@monstr.eu>
+Cc: Mikael Starvik <starvik@axis.com>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Rich Felker <dalias@libc.org>
+Cc: Richard Henderson <rth@twiddle.net>
+Cc: Richard Kuo <rkuo@codeaurora.org>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Russell King <linux@arm.linux.org.uk>
+Cc: Steven Miao <realmz6@gmail.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: Vineet Gupta <vgupta@synopsys.com>
+Cc: Will Deacon <will.deacon@arm.com>
+Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+ kernel/fork.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -1461,7 +1461,7 @@ static struct task_struct *copy_process(
+ pid = alloc_pid(p->nsproxy->pid_ns_for_children);
+ if (IS_ERR(pid)) {
+ retval = PTR_ERR(pid);
+- goto bad_fork_cleanup_io;
++ goto bad_fork_cleanup_thread;
+ }
+ }
+
+@@ -1623,6 +1623,8 @@ bad_fork_cancel_cgroup:
+ bad_fork_free_pid:
+ if (pid != &init_struct_pid)
+ free_pid(pid);
++bad_fork_cleanup_thread:
++ exit_thread(p);
+ bad_fork_cleanup_io:
+ if (p->io_context)
+ exit_io_context(p);
diff --git a/series.conf b/series.conf
index 6452cc4a64..a4be6ead74 100644
--- a/series.conf
+++ b/series.conf
@@ -312,6 +312,7 @@
patches.fixes/0001-mn10300-let-exit_fpu-accept-a-task.patch
patches.fixes/0002-exit_thread-remove-empty-bodies.patch
patches.fixes/0003-exit_thread-accept-a-task-parameter-to-be-exited.patch
+ patches.fixes/0004-fork-free-thread-in-copy_process-on-failure.patch
########################################################
# futex