mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] signal: Preserve the ptrace stop code for SIGCHLD notification
@ 2026-11-11  8:43 Zhu Jun
  2026-11-11 16:22 ` Oleg Nesterov
  0 siblings, 1 reply; 2+ messages in thread
From: Zhu Jun @ 2026-11-11  8:43 UTC (permalink / raw)
  To: oleg; +Cc: brauner, linux-kernel, syzbot+0f4d5234b6cb5e479e5d, Zhu Jun

After ptrace_stop() drops siglock, the tracer can consume the stop with
waitpid() and clear the tracee's exit_code. do_notify_parent_cldstop()
then rereads that field without siglock and can report CLD_TRAPPED with
a zero si_status instead of the stop signal.

Pass the stop code saved in ptrace_stop() to the notification helper.
The other notification reasons continue to obtain their status from
the existing group-stop and continuation state.

Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
Signed-off-by: Zhu Jun <zhujun2@cmss.chinamobile.com>
---
 kernel/signal.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index dd770e68faee..d3afa9b846f6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2346,6 +2346,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
  * @tsk: task reporting the state change
  * @for_ptracer: the notification is for ptracer
  * @why: CLD_{CONTINUED|STOPPED|TRAPPED} to report
+ * @exit_code: saved ptrace stop code when @why is CLD_TRAPPED
  *
  * Notify @tsk's parent that the stopped/continued state has changed.  If
  * @for_ptracer is %false, @tsk's group leader notifies to its real parent.
@@ -2355,7 +2356,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
  * Must be called with tasklist_lock at least read locked.
  */
 static void do_notify_parent_cldstop(struct task_struct *tsk,
-				     bool for_ptracer, int why)
+				     bool for_ptracer, int why, int exit_code)
 {
 	struct kernel_siginfo info;
 	unsigned long flags;
@@ -2394,7 +2395,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
  		info.si_status = tsk->signal->group_exit_code & 0x7f;
  		break;
  	case CLD_TRAPPED:
- 		info.si_status = tsk->exit_code & 0x7f;
+		info.si_status = exit_code & 0x7f;
  		break;
  	default:
  		BUG();
@@ -2512,9 +2513,9 @@ static int ptrace_stop(int exit_code, int why, unsigned long message,
 	 * separately unless they're gonna be duplicates.
 	 */
 	if (current->ptrace)
-		do_notify_parent_cldstop(current, true, why);
+		do_notify_parent_cldstop(current, true, why, exit_code);
 	if (gstop_done && (!current->ptrace || ptrace_reparented(current)))
-		do_notify_parent_cldstop(current, false, why);
+		do_notify_parent_cldstop(current, false, why, 0);
 
 	/*
 	 * The previous do_notify_parent_cldstop() invocation woke ptracer.
@@ -2710,7 +2711,7 @@ static bool do_signal_stop(int signr)
 		 */
 		if (notify) {
 			read_lock(&tasklist_lock);
-			do_notify_parent_cldstop(current, false, notify);
+			do_notify_parent_cldstop(current, false, notify, 0);
 			read_unlock(&tasklist_lock);
 		}
 
@@ -2927,11 +2928,11 @@ bool get_signal(struct ksignal *ksig)
 		 * a duplicate.
 		 */
 		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(current, false, why);
+		do_notify_parent_cldstop(current, false, why, 0);
 
 		if (ptrace_reparented(current->group_leader))
 			do_notify_parent_cldstop(current->group_leader,
-						true, why);
+						true, why, 0);
 		read_unlock(&tasklist_lock);
 
 		goto relock;
@@ -3235,7 +3236,7 @@ void exit_signals(struct task_struct *tsk)
 	 */
 	if (unlikely(group_stop)) {
 		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(tsk, false, group_stop);
+		do_notify_parent_cldstop(tsk, false, group_stop, 0);
 		read_unlock(&tasklist_lock);
 	}
 }
-- 
2.51.0




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] signal: Preserve the ptrace stop code for SIGCHLD notification
  2026-11-11  8:43 [PATCH] signal: Preserve the ptrace stop code for SIGCHLD notification Zhu Jun
@ 2026-11-11 16:22 ` Oleg Nesterov
  0 siblings, 0 replies; 2+ messages in thread
From: Oleg Nesterov @ 2026-11-11 16:22 UTC (permalink / raw)
  To: Zhu Jun; +Cc: brauner, linux-kernel, syzbot+0f4d5234b6cb5e479e5d

On 11/11, Zhu Jun wrote:
>
> After ptrace_stop() drops siglock, the tracer can consume the stop with
> waitpid() and clear the tracee's exit_code. do_notify_parent_cldstop()
> then rereads that field without siglock and can report CLD_TRAPPED with
> a zero si_status instead of the stop signal.
>
> Pass the stop code saved in ptrace_stop() to the notification helper.
> The other notification reasons continue to obtain their status from
> the existing group-stop and continuation state.

But how the "correct" .si_status can actually help debugger if it has
already consumed tsk->exit_code? Why do we want this change?

> Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")

Yes, this logic is very old. And unlikely useful.

I don't think userspace actually uses the siginfo which comes with SIGCHLD.
If nothing else, SIGCHLD doesn't queue, so si_code/si_status is not necessary
uptodate even if parent/debugger has a single child/tracee.

>  static void do_notify_parent_cldstop(struct task_struct *tsk,
> -				     bool for_ptracer, int why)
> +				     bool for_ptracer, int why, int exit_code)
>  {
>  	struct kernel_siginfo info;
>  	unsigned long flags;
> @@ -2394,7 +2395,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
>   		info.si_status = tsk->signal->group_exit_code & 0x7f;
>   		break;
>   	case CLD_TRAPPED:
> - 		info.si_status = tsk->exit_code & 0x7f;
> +		info.si_status = exit_code & 0x7f;

Note that tsk->signal->group_exit_code can be cleared by waitpid() the same way,
even if tsk is not traced, so this change is incomplete.

Again, I personally think we don't care.. Perhaps something like this patch makes
sense just to make this code look more correct, but then please consider the
CLD_STOPPED case as well.

Oleg.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-11 16:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11  8:43 [PATCH] signal: Preserve the ptrace stop code for SIGCHLD notification Zhu Jun
2026-11-11 16:22 ` Oleg Nesterov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®