From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755749AbbJUUbK (ORCPT ); Wed, 21 Oct 2015 16:31:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40823 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753885AbbJUUbI (ORCPT ); Wed, 21 Oct 2015 16:31:08 -0400 Message-ID: <5627F607.4050506@redhat.com> Date: Wed, 21 Oct 2015 22:31:03 +0200 From: Denys Vlasenko User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0 MIME-Version: 1.0 To: Andrew Morton , Oleg Nesterov CC: Dmitry Vyukov , Alexander Potapenko , Eric Dumazet , Jan Kratochvil , Julien Tinnes , Kees Cook , Kostya Serebryany , Linus Torvalds , "Michael Kerrisk (man-pages)" , Pedro Alves , Robert Swiecki , Roland McGrath , syzkaller@googlegroups.com, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/2] wait/ptrace: always assume __WALL if the child is traced References: <20151020171740.GA29290@redhat.com> <20151020171754.GA29304@redhat.com> <20151020153155.e03f4219da4014efe6f810b0@linux-foundation.org> <5627EE9E.8040600@redhat.com> In-Reply-To: <5627EE9E.8040600@redhat.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 10/21/2015 09:59 PM, Denys Vlasenko wrote: > On 10/21/2015 12:31 AM, Andrew Morton wrote: >> On Tue, 20 Oct 2015 19:17:54 +0200 Oleg Nesterov wrote: >> >>> The following program (simplified version of generated by syzkaller) >>> >>> #include >>> #include >>> #include >>> #include >>> #include >>> >>> void *thread_func(void *arg) >>> { >>> ptrace(PTRACE_TRACEME, 0,0,0); >>> return 0; >>> } >>> >>> int main(void) >>> { >>> pthread_t thread; >>> >>> if (fork()) >>> return 0; >>> >>> while (getppid() != 1) >>> ; >>> >>> pthread_create(&thread, NULL, thread_func, NULL); >>> pthread_join(thread, NULL); >>> return 0; >>> } >>> >>> creates the unreapable zombie if /sbin/init doesn't use __WALL. >>> >>> This is not a kernel bug, at least in a sense that everything works as >>> expected: debugger should reap a traced sub-thread before it can reap >>> the leader, but without __WALL/__WCLONE do_wait() ignores sub-threads. >>> >>> Unfortunately, it seems that /sbin/init in most (all?) distributions >>> doesn't use it and we have to change the kernel to avoid the problem. >> >> Well, to fix this a distro needs to roll out a new kernel. Or a new >> init(8). Is there any reason to believe that distributing/deploying a >> new kernel is significantly easier for everyone? Because fixing init >> sounds like a much preferable solution to this problem. > > People will continue to write new init(8) implementations, > and they will miss this obscure case. > > Before this bug was found, it was considered possible to use > a shell script as init process. What now, every shell needs to add > __WALL to its waitpids? > > The use of PTRACE_TRACEME in this reproducer is clearly pathological: > PTRACE_TRACEME was never intended to be used to attach to unsuspecting > processes. > > How about making PTRACE_TRACEME fail in this case? something like this diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 787320d..285a58c 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -385,6 +385,17 @@ static int ptrace_traceme(void) write_lock_irq(&tasklist_lock); /* Are we already being traced? */ if (!current->ptrace) { + struct pid_namespace *pid_ns; + + pid_ns = task_active_pid_ns(current->parent); + if (current->parent == pid_ns->child_reaper) { + /* + * Our parent is init. We may be a reparented process + * used for PTRACE_TRACEME zombie attack on init. + */ + goto nope; + } + ret = security_ptrace_traceme(current->parent); /* * Check PF_EXITING to ensure ->real_parent has not passed @@ -395,6 +406,7 @@ static int ptrace_traceme(void) current->ptrace = PT_PTRACED; __ptrace_link(current, current->real_parent); } + nope: ; } write_unlock_irq(&tasklist_lock);