All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrei Vagin <avagin@gmail.com>
To: Oleg Nesterov <oleg@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	linux-kernel@vger.kernel.org,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: Re: [PATCH] kernel: release ptraced tasks before zap_pid_ns_processes
Date: Tue, 8 Jan 2019 12:36:13 -0800	[thread overview]
Message-ID: <20190108203612.GA19454@gmail.com> (raw)
In-Reply-To: <20190108165043.GA10240@redhat.com>

On Tue, Jan 08, 2019 at 05:50:43PM +0100, Oleg Nesterov wrote:
> Sorry for delay, vacation,
> 
> On 01/02, Andrei Vagin wrote:
> >
> > zap_pid_ns_processes() can stuck on waiting tasks from the dead list. In
> > this case, we will have one unkillable process with one or more dead
> > children.
> 
> Thanks!
> 
> > --- a/kernel/exit.c
> > +++ b/kernel/exit.c
> > @@ -664,9 +664,6 @@ static void forget_original_parent(struct task_struct *father,
> >  {
> >  	struct task_struct *p, *t, *reaper;
> >  
> > -	if (unlikely(!list_empty(&father->ptraced)))
> > -		exit_ptrace(father, dead);
> > -
> >  	/* Can drop and reacquire tasklist_lock */
> >  	reaper = find_child_reaper(father);
> >  	if (list_empty(&father->children))
> > @@ -705,8 +702,18 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
> >  	LIST_HEAD(dead);
> >  
> >  	write_lock_irq(&tasklist_lock);
> > -	forget_original_parent(tsk, &dead);
> > +	if (unlikely(!list_empty(&tsk->ptraced)))
> > +		exit_ptrace(tsk, &dead);
> > +	write_unlock_irq(&tasklist_lock);
> > +
> > +	/* Ptraced tasks have to be released before zap_pid_ns_processes(). */
> > +	list_for_each_entry_safe(p, n, &dead, ptrace_entry) {
> > +		list_del_init(&p->ptrace_entry);
> > +		release_task(p);
> > +	}
> >  
> > +	write_lock_irq(&tasklist_lock);
> > +	forget_original_parent(tsk, &dead);
> >  	if (group_dead)
> >  		kill_orphaned_pgrp(tsk->group_leader, NULL);
> 
> How about a different fix below? It avoids additional write_lock/unlock(tasklist),
> and another list_for_each_entry_safe(dead) loop is called only if it is actually
> needed.
> 
> Or I missed something?

No, you don't. The patch looks really nice. Thanks!

BTW: We probably need to add the "Fixes:" tag, but I am not sure to which
commit, it looks like the issue is here for years.

Acked-by: Andrei Vagin <avagin@gmail.com>

> 
> Oleg.
> 
> 
> --- x/kernel/exit.c
> +++ x/kernel/exit.c
> @@ -558,12 +558,14 @@ static struct task_struct *find_alive_th
>  	return NULL;
>  }
>  
> -static struct task_struct *find_child_reaper(struct task_struct *father)
> +static struct task_struct *find_child_reaper(struct task_struct *father,
> +						struct list_head *dead)
>  	__releases(&tasklist_lock)
>  	__acquires(&tasklist_lock)
>  {
>  	struct pid_namespace *pid_ns = task_active_pid_ns(father);
>  	struct task_struct *reaper = pid_ns->child_reaper;
> +	struct task_struct *p, *n;
>  
>  	if (likely(reaper != father))
>  		return reaper;
> @@ -579,6 +581,11 @@ static struct task_struct *find_child_re
>  		panic("Attempted to kill init! exitcode=0x%08x\n",
>  			father->signal->group_exit_code ?: father->exit_code);
>  	}
> +
> +	list_for_each_entry_safe(p, n, &dead, ptrace_entry) {
> +		list_del_init(&p->ptrace_entry);
> +		release_task(p);
> +	}
>  	zap_pid_ns_processes(pid_ns);
>  	write_lock_irq(&tasklist_lock);
>  
> @@ -668,7 +675,7 @@ static void forget_original_parent(struc
>  		exit_ptrace(father, dead);
>  
>  	/* Can drop and reacquire tasklist_lock */
> -	reaper = find_child_reaper(father);
> +	reaper = find_child_reaper(father, dead);
>  	if (list_empty(&father->children))
>  		return;
>  
> 

  reply	other threads:[~2019-01-08 20:36 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-02 20:59 [PATCH] kernel: release ptraced tasks before zap_pid_ns_processes Andrei Vagin
2019-01-02 21:16 ` Andrei Vagin
2019-01-02 21:17 ` Andrei Vagin
2019-01-08 16:50 ` Oleg Nesterov
2019-01-08 20:36   ` Andrei Vagin [this message]
2019-01-09 17:08     ` Oleg Nesterov
2019-01-10  8:36       ` Andrei Vagin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190108203612.GA19454@gmail.com \
    --to=avagin@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=ebiederm@xmission.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.