From: Kirill Tkhai <ktk...@virtuozzo.com> [ Upstream commit 8896c23d2ef803f1883fea73117a435925c2b4c4 ]
alloc_pidmap() advances pid_namespace::last_pid. When first pid allocation fails, then next created process will have pid 2 and pid_ns_prepare_proc() won't be called. So, pid_namespace::proc_mnt will never be initialized (not to mention that there won't be a child reaper). I saw crash stack of such case on kernel 3.10: BUG: unable to handle kernel NULL pointer dereference at (null) IP: proc_flush_task+0x8f/0x1b0 Call Trace: release_task+0x3f/0x490 wait_consider_task.part.10+0x7ff/0xb00 do_wait+0x11f/0x280 SyS_wait4+0x7d/0x110 We may fix this by restore of last_pid in 0 or by prohibiting of futher allocations. Since there was a similar issue in Oleg Nesterov's commit 314a8ad0f18a ("pidns: fix free_pid() to handle the first fork failure"). and it was fixed via prohibiting allocation, let's follow this way, and do the same. Link: http://lkml.kernel.org/r/149201021004.4863.6762095011554287922.stgit@localhost.localdomain Signed-off-by: Kirill Tkhai <ktk...@virtuozzo.com> Acked-by: Cyrill Gorcunov <gorcu...@openvz.org> Cc: Andrei Vagin <ava...@virtuozzo.com> Cc: Andreas Gruenbacher <agrue...@redhat.com> Cc: Kees Cook <keesc...@chromium.org> Cc: Michael Kerrisk <mtk.manpa...@googlemail.com> Cc: Al Viro <v...@zeniv.linux.org.uk> Cc: Oleg Nesterov <o...@redhat.com> Cc: Paul Moore <p...@paul-moore.com> Cc: Eric Biederman <ebied...@xmission.com> Cc: Andy Lutomirski <l...@amacapital.net> Cc: Ingo Molnar <mi...@kernel.org> Cc: Serge Hallyn <se...@hallyn.com> Signed-off-by: Andrew Morton <a...@linux-foundation.org> Signed-off-by: Linus Torvalds <torva...@linux-foundation.org> Signed-off-by: Sasha Levin <alexander.le...@microsoft.com> --- kernel/pid.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/pid.c b/kernel/pid.c index 693a64385d59..fa704f88ff8e 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -322,8 +322,10 @@ struct pid *alloc_pid(struct pid_namespace *ns) } if (unlikely(is_child_reaper(pid))) { - if (pid_ns_prepare_proc(ns)) + if (pid_ns_prepare_proc(ns)) { + disable_pid_allocation(ns); goto out_free; + } } get_pid_ns(ns); -- 2.14.1