Re: [PATCH] pidfs: cleanup the usage of do_notify_pidfd()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Mar 23, 2025 at 06:19:55PM +0100, Oleg Nesterov wrote:
> If a single-threaded process exits do_notify_pidfd() will be called twice,
> from exit_notify() and right after that from do_notify_parent().
> 
> 1. Change exit_notify() to call do_notify_pidfd() if the exiting task is
>    not ptraced and it is not a group leader.
> 
> 2. Change do_notify_parent() to call do_notify_pidfd() unconditionally.
> 
>    If tsk is not ptraced, do_notify_parent() will only be called when it
>    is a group-leader and thread_group_empty() is true.
> 
> This means that if tsk is ptraced, do_notify_pidfd() will be called from
> do_notify_parent() even if tsk is a delay_group_leader(). But this case is
> less common, and apart from the unnecessary __wake_up() is harmless.
> 
> Granted, this unnecessary __wake_up() can be avoided, but I don't want to
> do it in this patch because it's just a consequence of another historical
> oddity: we notify the tracer even if !thread_group_empty(), but do_wait()
> from debugger can't work until all other threads exit. With or without this
> patch we should either eliminate do_notify_parent() in this case, or change
> do_wait(WEXITED) to untrace the ptraced delay_group_leader() at least when
> ptrace_reparented().
> 
> Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx>
> ---

Thanks for doing this! I'll send this together with the first set of
fixes after the merge window closes.

>  kernel/exit.c   | 8 ++------
>  kernel/signal.c | 8 +++-----
>  2 files changed, 5 insertions(+), 11 deletions(-)
> 
> diff --git a/kernel/exit.c b/kernel/exit.c
> index 683766316a3d..d0ebccb9dec0 100644
> --- a/kernel/exit.c
> +++ b/kernel/exit.c
> @@ -742,12 +742,6 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
>  		kill_orphaned_pgrp(tsk->group_leader, NULL);
>  
>  	tsk->exit_state = EXIT_ZOMBIE;
> -	/*
> -	 * Ignore thread-group leaders that exited before all
> -	 * subthreads did.
> -	 */
> -	if (!delay_group_leader(tsk))
> -		do_notify_pidfd(tsk);
>  
>  	if (unlikely(tsk->ptrace)) {
>  		int sig = thread_group_leader(tsk) &&
> @@ -760,6 +754,8 @@ static void exit_notify(struct task_struct *tsk, int group_dead)
>  			do_notify_parent(tsk, tsk->exit_signal);
>  	} else {
>  		autoreap = true;
> +		/* untraced sub-thread */
> +		do_notify_pidfd(tsk);
>  	}
>  
>  	if (autoreap) {
> diff --git a/kernel/signal.c b/kernel/signal.c
> index 027ad9e97417..1d8db0dabb71 100644
> --- a/kernel/signal.c
> +++ b/kernel/signal.c
> @@ -2179,11 +2179,9 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
>  
>  	WARN_ON_ONCE(!tsk->ptrace &&
>  	       (tsk->group_leader != tsk || !thread_group_empty(tsk)));
> -	/*
> -	 * Notify for thread-group leaders without subthreads.
> -	 */
> -	if (thread_group_empty(tsk))
> -		do_notify_pidfd(tsk);
> +
> +	/* ptraced, or group-leader without sub-threads */
> +	do_notify_pidfd(tsk);
>  
>  	if (sig != SIGCHLD) {
>  		/*
> -- 
> 2.25.1.362.g51ebf55
> 
> 




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux