All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Eric W. Biederman" <ebiederm@xmission.com>
To: linux-kernel@vger.kernel.org
Cc: rjw@rjwysocki.net, Oleg Nesterov <oleg@redhat.com>,
	mingo@kernel.org, vincent.guittot@linaro.org,
	dietmar.eggemann@arm.com, rostedt@goodmis.org, mgorman@suse.de,
	bigeasy@linutronix.de, Will Deacon <will@kernel.org>,
	tj@kernel.org, linux-pm@vger.kernel.org,
	Peter Zijlstra <peterz@infradead.org>,
	Richard Weinberger <richard@nod.at>,
	Anton Ivanov <anton.ivanov@cambridgegreys.com>,
	Johannes Berg <johannes@sipsolutions.net>,
	linux-um@lists.infradead.org, Chris Zankel <chris@zankel.net>,
	Max Filippov <jcmvbkbc@gmail.com>,
	linux-xtensa@linux-xtensa.org, Kees Cook <keescook@chromium.org>,
	Jann Horn <jannh@google.com>,
	linux-ia64@vger.kernel.org, Robert OCallahan <roc@pernos.co>,
	Kyle Huey <khuey@pernos.co>, Richard Henderson <rth@twiddle.net>,
	Ivan Kokshaysky <ink@jurassic.park.msu.ru>,
	Matt Turner <mattst88@gmail.com>,
	Jason Wessel <jason.wessel@windriver.com>,
	Daniel Thompson <daniel.thompson@linaro.org>,
	Douglas Anderson <dianders@chromium.org>,
	Douglas Miller <dougmill@linux.vnet.ibm.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: [PATCH 16/16] signal: Always call do_notify_parent_cldstop with siglock held
Date: Wed, 18 May 2022 17:53:55 -0500	[thread overview]
Message-ID: <20220518225355.784371-16-ebiederm@xmission.com> (raw)
In-Reply-To: <871qwq5ucx.fsf_-_@email.froward.int.ebiederm.org>

Now that siglock keeps tsk->parent and tsk->real_parent constant
require that do_notify_parent_cldstop is called with tsk->siglock held
instead of the tasklist_lock.

As all of the callers of do_notify_parent_cldstop had to drop the
siglock and take tasklist_lock this simplifies all of it's callers.

This removes one reason for taking tasklist_lock.

This makes ptrace_stop so that it should reliably work correctly and
reliably with PREEMPT_RT enabled and CONFIG_CGROUPS disabled.  The
remaining challenge is that cgroup_enter_frozen takes spin_lock after
__state has been set to TASK_TRACED.  Which on PREEMPT_RT means the
code can sleep and change __state.  Not only that but it means that
wait_task_inactive could potentially detect the code scheduling away
at that point and fail, causing ptrace_check_attach to fail.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 262 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 189 insertions(+), 73 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index 2cc45e8448e2..d4956be51939 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1994,6 +1994,129 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)
 	return ret;
 }
 
+/**
+ * lock_parents_siglocks - Take current, real_parent, and parent's siglock
+ * @lock_tracer: The tracers siglock is needed.
+ *
+ * There is no natural ordering to these locks so they must be sorted
+ * before being taken.
+ *
+ * There are two complicating factors here:
+ * - The locks live in sighand and sighand can be arbitrarily shared
+ * - parent and real_parent can change when current's siglock is unlocked.
+ *
+ * To deal with this first the all of the sighand pointers are
+ * gathered under current's siglock, and the sighand pointers are
+ * sorted.  As siglock lives inside of sighand this also sorts the
+ * siglock's by address.
+ *
+ * Then the siglocks are taken in order dropping current's siglock if
+ * necessary.
+ *
+ * Finally if parent and real_parent have not changed return.
+ * If they either parent has changed drop their locks and try again.
+ *
+ * Changing sighand is an infrequent and somewhat expensive operation
+ * (unshare or exec) and so even in the worst case this loop
+ * should not loop too many times before all of the proper locks are
+ * taken in order.
+ *
+ * CONTEXT:
+ * Must be called with @current->sighand->siglock held
+ *
+ * RETURNS:
+ * current's, real_parent's, and parent's siglock held.
+ */
+static void lock_parents_siglocks(bool lock_tracer)
+	__releases(&current->sighand->siglock)
+	__acquires(&current->sighand->siglock)
+	__acquires(&current->real_parent->sighand->siglock)
+	__acquires(&current->parent->sighand->siglock)
+{
+	struct task_struct *me = current;
+	struct sighand_struct *m_sighand = me->sighand;
+
+	lockdep_assert_held(&m_sighand->siglock);
+
+	rcu_read_lock();
+	for (;;) {
+		struct task_struct *parent, *tracer;
+		struct sighand_struct *p_sighand, *t_sighand, *s1, *s2, *s3;
+
+		parent = me->real_parent;
+		tracer = ptrace_parent(me);
+		if (!tracer || !lock_tracer)
+			tracer = parent;
+
+		p_sighand = rcu_dereference(parent->sighand);
+		t_sighand = rcu_dereference(tracer->sighand);
+
+		/* Sort the sighands so that s1 >= s2 >= s3 */
+		s1 = m_sighand;
+		s2 = p_sighand;
+		s3 = t_sighand;
+		if (s1 > s2)
+			swap(s1, s2);
+		if (s1 > s3)
+			swap(s1, s3);
+		if (s2 > s3)
+			swap(s2, s3);
+
+		/* Take the locks in order */
+		if (s1 != m_sighand) {
+			spin_unlock(&m_sighand->siglock);
+			spin_lock(&s1->siglock);
+		}
+		if (s1 != s2)
+			spin_lock_nested(&s2->siglock, 1);
+		if (s2 != s3)
+			spin_lock_nested(&s3->siglock, 2);
+
+		/* Verify the proper locks are held */
+		if (likely((s1 == m_sighand) ||
+			   ((me->real_parent == parent) &&
+			    (me->parent == tracer) &&
+			    (parent->sighand == p_sighand) &&
+			    (tracer->sighand == t_sighand)))) {
+			break;
+		}
+
+		/* Drop all but current's siglock */
+		if (p_sighand != m_sighand)
+			spin_unlock(&p_sighand->siglock);
+		if (t_sighand != p_sighand)
+			spin_unlock(&t_sighand->siglock);
+
+		/*
+		 * Since [pt]_sighand will likely change if we go
+		 * around, and m_sighand is the only one held, make sure
+		 * it is subclass-0, since the above 's1 != m_sighand'
+		 * clause very much relies on that.
+		 */
+		lock_set_subclass(&m_sighand->siglock.dep_map, 0, _RET_IP_);
+	}
+	rcu_read_unlock();
+}
+
+static void unlock_parents_siglocks(bool unlock_tracer)
+	__releases(&current->real_parent->sighand->siglock)
+	__releases(&current->parent->sighand->siglock)
+{
+	struct task_struct *me = current;
+	struct task_struct *parent = me->real_parent;
+	struct task_struct *tracer = ptrace_parent(me);
+	struct sighand_struct *m_sighand = me->sighand;
+	struct sighand_struct *p_sighand = parent->sighand;
+
+	if (p_sighand != m_sighand)
+		spin_unlock(&p_sighand->siglock);
+	if (tracer && unlock_tracer) {
+		struct sighand_struct *t_sighand = tracer->sighand;
+		if (t_sighand != p_sighand)
+			spin_unlock(&t_sighand->siglock);
+	}
+}
+
 static void do_notify_pidfd(struct task_struct *task)
 {
 	struct pid *pid;
@@ -2125,11 +2248,12 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 				     bool for_ptracer, int why)
 {
 	struct kernel_siginfo info;
-	unsigned long flags;
 	struct task_struct *parent;
 	struct sighand_struct *sighand;
 	u64 utime, stime;
 
+	lockdep_assert_held(&tsk->sighand->siglock);
+
 	if (for_ptracer) {
 		parent = tsk->parent;
 	} else {
@@ -2137,6 +2261,8 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 		parent = tsk->real_parent;
 	}
 
+	lockdep_assert_held(&parent->sighand->siglock);
+
 	clear_siginfo(&info);
 	info.si_signo = SIGCHLD;
 	info.si_errno = 0;
@@ -2168,7 +2294,6 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
  	}
 
 	sighand = parent->sighand;
-	spin_lock_irqsave(&sighand->siglock, flags);
 	if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
 	    !(sighand->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 		send_signal_locked(SIGCHLD, &info, parent, PIDTYPE_TGID);
@@ -2176,7 +2301,6 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 	 * Even if SIGCHLD is not generated, we must wake up wait4 calls.
 	 */
 	__wake_up_parent(tsk, parent);
-	spin_unlock_irqrestore(&sighand->siglock, flags);
 }
 
 /*
@@ -2208,14 +2332,18 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 		spin_lock_irq(&current->sighand->siglock);
 	}
 
+	lock_parents_siglocks(true);
 	/*
 	 * After this point ptrace_signal_wake_up or signal_wake_up
 	 * will clear TASK_TRACED if ptrace_unlink happens or a fatal
 	 * signal comes in.  Handle previous ptrace_unlinks and fatal
 	 * signals here to prevent ptrace_stop sleeping in schedule.
 	 */
-	if (!current->ptrace || __fatal_signal_pending(current))
+
+	if (!current->ptrace || __fatal_signal_pending(current)) {
+		unlock_parents_siglocks(true);
 		return;
+	}
 
 	set_special_state(TASK_TRACED);
 	current->jobctl |= JOBCTL_TRACED;
@@ -2254,16 +2382,6 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 	if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
 		gstop_done = task_participate_group_stop(current);
 
-	/* any trap clears pending STOP trap, STOP trap clears NOTIFY */
-	task_clear_jobctl_pending(current, JOBCTL_TRAP_STOP);
-	if (info && info->si_code >> 8 == PTRACE_EVENT_STOP)
-		task_clear_jobctl_pending(current, JOBCTL_TRAP_NOTIFY);
-
-	/* entering a trap, clear TRAPPING */
-	task_clear_jobctl_trapping(current);
-
-	spin_unlock_irq(&current->sighand->siglock);
-	read_lock(&tasklist_lock);
 	/*
 	 * Notify parents of the stop.
 	 *
@@ -2279,14 +2397,25 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 	if (gstop_done && (!current->ptrace || ptrace_reparented(current)))
 		do_notify_parent_cldstop(current, false, why);
 
+	unlock_parents_siglocks(true);
+
+	/* any trap clears pending STOP trap, STOP trap clears NOTIFY */
+	task_clear_jobctl_pending(current, JOBCTL_TRAP_STOP);
+	if (info && info->si_code >> 8 == PTRACE_EVENT_STOP)
+		task_clear_jobctl_pending(current, JOBCTL_TRAP_NOTIFY);
+
+	/* entering a trap, clear TRAPPING */
+	task_clear_jobctl_trapping(current);
+
 	/*
 	 * Don't want to allow preemption here, because
 	 * sys_ptrace() needs this task to be inactive.
 	 *
-	 * XXX: implement read_unlock_no_resched().
+	 * XXX: implement spin_unlock_no_resched().
 	 */
 	preempt_disable();
-	read_unlock(&tasklist_lock);
+	spin_unlock_irq(&current->sighand->siglock);
+
 	cgroup_enter_frozen();
 	preempt_enable_no_resched();
 	freezable_schedule();
@@ -2361,8 +2490,8 @@ int ptrace_notify(int exit_code, unsigned long message)
  * on %true return.
  *
  * RETURNS:
- * %false if group stop is already cancelled or ptrace trap is scheduled.
- * %true if participated in group stop.
+ * %false if group stop is already cancelled.
+ * %true otherwise (as lock_parents_siglocks may have dropped siglock).
  */
 static bool do_signal_stop(int signr)
 	__releases(&current->sighand->siglock)
@@ -2425,36 +2554,24 @@ static bool do_signal_stop(int signr)
 		}
 	}
 
+	lock_parents_siglocks(false);
+	/* Recheck JOBCTL_STOP_PENDING after unlock+lock of siglock */
+	if (unlikely(!(current->jobctl & JOBCTL_STOP_PENDING)))
+		goto out;
 	if (likely(!current->ptrace)) {
-		int notify = 0;
-
 		/*
 		 * If there are no other threads in the group, or if there
 		 * is a group stop in progress and we are the last to stop,
-		 * report to the parent.
+		 * report to the real_parent.
 		 */
 		if (task_participate_group_stop(current))
-			notify = CLD_STOPPED;
+			do_notify_parent_cldstop(current, false, CLD_STOPPED);
+		unlock_parents_siglocks(false);
 
 		current->jobctl |= JOBCTL_STOPPED;
 		set_special_state(TASK_STOPPED);
 		spin_unlock_irq(&current->sighand->siglock);
 
-		/*
-		 * Notify the parent of the group stop completion.  Because
-		 * we're not holding either the siglock or tasklist_lock
-		 * here, ptracer may attach inbetween; however, this is for
-		 * group stop and should always be delivered to the real
-		 * parent of the group leader.  The new ptracer will get
-		 * its notification when this task transitions into
-		 * TASK_TRACED.
-		 */
-		if (notify) {
-			read_lock(&tasklist_lock);
-			do_notify_parent_cldstop(current, false, notify);
-			read_unlock(&tasklist_lock);
-		}
-
 		/* Now we don't run again until woken by SIGCONT or SIGKILL */
 		cgroup_enter_frozen();
 		freezable_schedule();
@@ -2465,8 +2582,11 @@ static bool do_signal_stop(int signr)
 		 * Schedule it and let the caller deal with it.
 		 */
 		task_set_jobctl_pending(current, JOBCTL_TRAP_STOP);
-		return false;
 	}
+out:
+	unlock_parents_siglocks(false);
+	spin_unlock_irq(&current->sighand->siglock);
+	return true;
 }
 
 /**
@@ -2624,32 +2744,30 @@ bool get_signal(struct ksignal *ksig)
 	if (unlikely(signal->flags & SIGNAL_CLD_MASK)) {
 		int why;
 
-		if (signal->flags & SIGNAL_CLD_CONTINUED)
-			why = CLD_CONTINUED;
-		else
-			why = CLD_STOPPED;
+		lock_parents_siglocks(true);
+		/* Recheck signal->flags after unlock+lock of siglock */
+		if (likely(signal->flags & SIGNAL_CLD_MASK)) {
+			if (signal->flags & SIGNAL_CLD_CONTINUED)
+				why = CLD_CONTINUED;
+			else
+				why = CLD_STOPPED;
 
-		signal->flags &= ~SIGNAL_CLD_MASK;
+			signal->flags &= ~SIGNAL_CLD_MASK;
 
-		spin_unlock_irq(&sighand->siglock);
-
-		/*
-		 * Notify the parent that we're continuing.  This event is
-		 * always per-process and doesn't make whole lot of sense
-		 * for ptracers, who shouldn't consume the state via
-		 * wait(2) either, but, for backward compatibility, notify
-		 * the ptracer of the group leader too unless it's gonna be
-		 * a duplicate.
-		 */
-		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(current, false, why);
-
-		if (ptrace_reparented(current->group_leader))
-			do_notify_parent_cldstop(current->group_leader,
-						true, why);
-		read_unlock(&tasklist_lock);
-
-		goto relock;
+			/*
+			 * Notify the parent that we're continuing.  This event is
+			 * always per-process and doesn't make whole lot of sense
+			 * for ptracers, who shouldn't consume the state via
+			 * wait(2) either, but, for backward compatibility, notify
+			 * the ptracer of the group leader too unless it's gonna be
+			 * a duplicate.
+			 */
+			do_notify_parent_cldstop(current, false, why);
+			if (ptrace_reparented(current->group_leader))
+				do_notify_parent_cldstop(current->group_leader,
+							 true, why);
+		}
+		unlock_parents_siglocks(true);
 	}
 
 	for (;;) {
@@ -2906,7 +3024,6 @@ static void retarget_shared_pending(struct task_struct *tsk, sigset_t *which)
 
 void exit_signals(struct task_struct *tsk)
 {
-	int group_stop = 0;
 	sigset_t unblocked;
 
 	/*
@@ -2937,21 +3054,20 @@ void exit_signals(struct task_struct *tsk)
 	signotset(&unblocked);
 	retarget_shared_pending(tsk, &unblocked);
 
-	if (unlikely(tsk->jobctl & JOBCTL_STOP_PENDING) &&
-	    task_participate_group_stop(tsk))
-		group_stop = CLD_STOPPED;
-out:
-	spin_unlock_irq(&tsk->sighand->siglock);
-
 	/*
 	 * If group stop has completed, deliver the notification.  This
 	 * should always go to the real parent of the group leader.
 	 */
-	if (unlikely(group_stop)) {
-		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(tsk, false, group_stop);
-		read_unlock(&tasklist_lock);
+	if (unlikely(tsk->jobctl & JOBCTL_STOP_PENDING)) {
+		lock_parents_siglocks(false);
+		/* Recheck JOBCTL_STOP_PENDING after unlock+lock of siglock */
+		if ((tsk->jobctl & JOBCTL_STOP_PENDING) &&
+		    task_participate_group_stop(tsk))
+			do_notify_parent_cldstop(tsk, false, CLD_STOPPED);
+		unlock_parents_siglocks(false);
 	}
+out:
+	spin_unlock_irq(&tsk->sighand->siglock);
 }
 
 /*
-- 
2.35.3


WARNING: multiple messages have this Message-ID (diff)
From: "Eric W. Biederman" <ebiederm@xmission.com>
To: linux-kernel@vger.kernel.org
Cc: rjw@rjwysocki.net, Oleg Nesterov <oleg@redhat.com>,
	mingo@kernel.org, vincent.guittot@linaro.org,
	dietmar.eggemann@arm.com, rostedt@goodmis.org, mgorman@suse.de,
	bigeasy@linutronix.de, Will Deacon <will@kernel.org>,
	tj@kernel.org, linux-pm@vger.kernel.org,
	Peter Zijlstra <peterz@infradead.org>,
	Richard Weinberger <richard@nod.at>,
	Anton Ivanov <anton.ivanov@cambridgegreys.com>,
	Johannes Berg <johannes@sipsolutions.net>,
	linux-um@lists.infradead.org, Chris Zankel <chris@zankel.net>,
	Max Filippov <jcmvbkbc@gmail.com>,
	linux-xtensa@linux-xtensa.org, Kees Cook <keescook@chromium.org>,
	Jann Horn <jannh@google.com>,
	linux-ia64@vger.kernel.org, Robert OCallahan <roc@pernos.co>,
	Kyle Huey <khuey@pernos.co>, Richard Henderson <rth@twiddle.net>,
	Ivan Kokshaysky <ink@jurassic.park.msu.ru>,
	Matt Turner <mattst88@gmail.com>,
	Jason Wessel <jason.wessel@windriver.com>,
	Daniel Thompson <daniel.thompson@linaro.org>,
	Douglas Anderson <dianders@chromium.org>,
	Douglas Miller <dougmill@linux.vnet.ibm.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: [PATCH 16/16] signal: Always call do_notify_parent_cldstop with siglock held
Date: Wed, 18 May 2022 17:53:55 -0500	[thread overview]
Message-ID: <20220518225355.784371-16-ebiederm@xmission.com> (raw)
In-Reply-To: <871qwq5ucx.fsf_-_@email.froward.int.ebiederm.org>

Now that siglock keeps tsk->parent and tsk->real_parent constant
require that do_notify_parent_cldstop is called with tsk->siglock held
instead of the tasklist_lock.

As all of the callers of do_notify_parent_cldstop had to drop the
siglock and take tasklist_lock this simplifies all of it's callers.

This removes one reason for taking tasklist_lock.

This makes ptrace_stop so that it should reliably work correctly and
reliably with PREEMPT_RT enabled and CONFIG_CGROUPS disabled.  The
remaining challenge is that cgroup_enter_frozen takes spin_lock after
__state has been set to TASK_TRACED.  Which on PREEMPT_RT means the
code can sleep and change __state.  Not only that but it means that
wait_task_inactive could potentially detect the code scheduling away
at that point and fail, causing ptrace_check_attach to fail.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 262 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 189 insertions(+), 73 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index 2cc45e8448e2..d4956be51939 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1994,6 +1994,129 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)
 	return ret;
 }
 
+/**
+ * lock_parents_siglocks - Take current, real_parent, and parent's siglock
+ * @lock_tracer: The tracers siglock is needed.
+ *
+ * There is no natural ordering to these locks so they must be sorted
+ * before being taken.
+ *
+ * There are two complicating factors here:
+ * - The locks live in sighand and sighand can be arbitrarily shared
+ * - parent and real_parent can change when current's siglock is unlocked.
+ *
+ * To deal with this first the all of the sighand pointers are
+ * gathered under current's siglock, and the sighand pointers are
+ * sorted.  As siglock lives inside of sighand this also sorts the
+ * siglock's by address.
+ *
+ * Then the siglocks are taken in order dropping current's siglock if
+ * necessary.
+ *
+ * Finally if parent and real_parent have not changed return.
+ * If they either parent has changed drop their locks and try again.
+ *
+ * Changing sighand is an infrequent and somewhat expensive operation
+ * (unshare or exec) and so even in the worst case this loop
+ * should not loop too many times before all of the proper locks are
+ * taken in order.
+ *
+ * CONTEXT:
+ * Must be called with @current->sighand->siglock held
+ *
+ * RETURNS:
+ * current's, real_parent's, and parent's siglock held.
+ */
+static void lock_parents_siglocks(bool lock_tracer)
+	__releases(&current->sighand->siglock)
+	__acquires(&current->sighand->siglock)
+	__acquires(&current->real_parent->sighand->siglock)
+	__acquires(&current->parent->sighand->siglock)
+{
+	struct task_struct *me = current;
+	struct sighand_struct *m_sighand = me->sighand;
+
+	lockdep_assert_held(&m_sighand->siglock);
+
+	rcu_read_lock();
+	for (;;) {
+		struct task_struct *parent, *tracer;
+		struct sighand_struct *p_sighand, *t_sighand, *s1, *s2, *s3;
+
+		parent = me->real_parent;
+		tracer = ptrace_parent(me);
+		if (!tracer || !lock_tracer)
+			tracer = parent;
+
+		p_sighand = rcu_dereference(parent->sighand);
+		t_sighand = rcu_dereference(tracer->sighand);
+
+		/* Sort the sighands so that s1 >= s2 >= s3 */
+		s1 = m_sighand;
+		s2 = p_sighand;
+		s3 = t_sighand;
+		if (s1 > s2)
+			swap(s1, s2);
+		if (s1 > s3)
+			swap(s1, s3);
+		if (s2 > s3)
+			swap(s2, s3);
+
+		/* Take the locks in order */
+		if (s1 != m_sighand) {
+			spin_unlock(&m_sighand->siglock);
+			spin_lock(&s1->siglock);
+		}
+		if (s1 != s2)
+			spin_lock_nested(&s2->siglock, 1);
+		if (s2 != s3)
+			spin_lock_nested(&s3->siglock, 2);
+
+		/* Verify the proper locks are held */
+		if (likely((s1 == m_sighand) ||
+			   ((me->real_parent == parent) &&
+			    (me->parent == tracer) &&
+			    (parent->sighand == p_sighand) &&
+			    (tracer->sighand == t_sighand)))) {
+			break;
+		}
+
+		/* Drop all but current's siglock */
+		if (p_sighand != m_sighand)
+			spin_unlock(&p_sighand->siglock);
+		if (t_sighand != p_sighand)
+			spin_unlock(&t_sighand->siglock);
+
+		/*
+		 * Since [pt]_sighand will likely change if we go
+		 * around, and m_sighand is the only one held, make sure
+		 * it is subclass-0, since the above 's1 != m_sighand'
+		 * clause very much relies on that.
+		 */
+		lock_set_subclass(&m_sighand->siglock.dep_map, 0, _RET_IP_);
+	}
+	rcu_read_unlock();
+}
+
+static void unlock_parents_siglocks(bool unlock_tracer)
+	__releases(&current->real_parent->sighand->siglock)
+	__releases(&current->parent->sighand->siglock)
+{
+	struct task_struct *me = current;
+	struct task_struct *parent = me->real_parent;
+	struct task_struct *tracer = ptrace_parent(me);
+	struct sighand_struct *m_sighand = me->sighand;
+	struct sighand_struct *p_sighand = parent->sighand;
+
+	if (p_sighand != m_sighand)
+		spin_unlock(&p_sighand->siglock);
+	if (tracer && unlock_tracer) {
+		struct sighand_struct *t_sighand = tracer->sighand;
+		if (t_sighand != p_sighand)
+			spin_unlock(&t_sighand->siglock);
+	}
+}
+
 static void do_notify_pidfd(struct task_struct *task)
 {
 	struct pid *pid;
@@ -2125,11 +2248,12 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 				     bool for_ptracer, int why)
 {
 	struct kernel_siginfo info;
-	unsigned long flags;
 	struct task_struct *parent;
 	struct sighand_struct *sighand;
 	u64 utime, stime;
 
+	lockdep_assert_held(&tsk->sighand->siglock);
+
 	if (for_ptracer) {
 		parent = tsk->parent;
 	} else {
@@ -2137,6 +2261,8 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 		parent = tsk->real_parent;
 	}
 
+	lockdep_assert_held(&parent->sighand->siglock);
+
 	clear_siginfo(&info);
 	info.si_signo = SIGCHLD;
 	info.si_errno = 0;
@@ -2168,7 +2294,6 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
  	}
 
 	sighand = parent->sighand;
-	spin_lock_irqsave(&sighand->siglock, flags);
 	if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
 	    !(sighand->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 		send_signal_locked(SIGCHLD, &info, parent, PIDTYPE_TGID);
@@ -2176,7 +2301,6 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 	 * Even if SIGCHLD is not generated, we must wake up wait4 calls.
 	 */
 	__wake_up_parent(tsk, parent);
-	spin_unlock_irqrestore(&sighand->siglock, flags);
 }
 
 /*
@@ -2208,14 +2332,18 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 		spin_lock_irq(&current->sighand->siglock);
 	}
 
+	lock_parents_siglocks(true);
 	/*
 	 * After this point ptrace_signal_wake_up or signal_wake_up
 	 * will clear TASK_TRACED if ptrace_unlink happens or a fatal
 	 * signal comes in.  Handle previous ptrace_unlinks and fatal
 	 * signals here to prevent ptrace_stop sleeping in schedule.
 	 */
-	if (!current->ptrace || __fatal_signal_pending(current))
+
+	if (!current->ptrace || __fatal_signal_pending(current)) {
+		unlock_parents_siglocks(true);
 		return;
+	}
 
 	set_special_state(TASK_TRACED);
 	current->jobctl |= JOBCTL_TRACED;
@@ -2254,16 +2382,6 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 	if (why == CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
 		gstop_done = task_participate_group_stop(current);
 
-	/* any trap clears pending STOP trap, STOP trap clears NOTIFY */
-	task_clear_jobctl_pending(current, JOBCTL_TRAP_STOP);
-	if (info && info->si_code >> 8 == PTRACE_EVENT_STOP)
-		task_clear_jobctl_pending(current, JOBCTL_TRAP_NOTIFY);
-
-	/* entering a trap, clear TRAPPING */
-	task_clear_jobctl_trapping(current);
-
-	spin_unlock_irq(&current->sighand->siglock);
-	read_lock(&tasklist_lock);
 	/*
 	 * Notify parents of the stop.
 	 *
@@ -2279,14 +2397,25 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 	if (gstop_done && (!current->ptrace || ptrace_reparented(current)))
 		do_notify_parent_cldstop(current, false, why);
 
+	unlock_parents_siglocks(true);
+
+	/* any trap clears pending STOP trap, STOP trap clears NOTIFY */
+	task_clear_jobctl_pending(current, JOBCTL_TRAP_STOP);
+	if (info && info->si_code >> 8 == PTRACE_EVENT_STOP)
+		task_clear_jobctl_pending(current, JOBCTL_TRAP_NOTIFY);
+
+	/* entering a trap, clear TRAPPING */
+	task_clear_jobctl_trapping(current);
+
 	/*
 	 * Don't want to allow preemption here, because
 	 * sys_ptrace() needs this task to be inactive.
 	 *
-	 * XXX: implement read_unlock_no_resched().
+	 * XXX: implement spin_unlock_no_resched().
 	 */
 	preempt_disable();
-	read_unlock(&tasklist_lock);
+	spin_unlock_irq(&current->sighand->siglock);
+
 	cgroup_enter_frozen();
 	preempt_enable_no_resched();
 	freezable_schedule();
@@ -2361,8 +2490,8 @@ int ptrace_notify(int exit_code, unsigned long message)
  * on %true return.
  *
  * RETURNS:
- * %false if group stop is already cancelled or ptrace trap is scheduled.
- * %true if participated in group stop.
+ * %false if group stop is already cancelled.
+ * %true otherwise (as lock_parents_siglocks may have dropped siglock).
  */
 static bool do_signal_stop(int signr)
 	__releases(&current->sighand->siglock)
@@ -2425,36 +2554,24 @@ static bool do_signal_stop(int signr)
 		}
 	}
 
+	lock_parents_siglocks(false);
+	/* Recheck JOBCTL_STOP_PENDING after unlock+lock of siglock */
+	if (unlikely(!(current->jobctl & JOBCTL_STOP_PENDING)))
+		goto out;
 	if (likely(!current->ptrace)) {
-		int notify = 0;
-
 		/*
 		 * If there are no other threads in the group, or if there
 		 * is a group stop in progress and we are the last to stop,
-		 * report to the parent.
+		 * report to the real_parent.
 		 */
 		if (task_participate_group_stop(current))
-			notify = CLD_STOPPED;
+			do_notify_parent_cldstop(current, false, CLD_STOPPED);
+		unlock_parents_siglocks(false);
 
 		current->jobctl |= JOBCTL_STOPPED;
 		set_special_state(TASK_STOPPED);
 		spin_unlock_irq(&current->sighand->siglock);
 
-		/*
-		 * Notify the parent of the group stop completion.  Because
-		 * we're not holding either the siglock or tasklist_lock
-		 * here, ptracer may attach inbetween; however, this is for
-		 * group stop and should always be delivered to the real
-		 * parent of the group leader.  The new ptracer will get
-		 * its notification when this task transitions into
-		 * TASK_TRACED.
-		 */
-		if (notify) {
-			read_lock(&tasklist_lock);
-			do_notify_parent_cldstop(current, false, notify);
-			read_unlock(&tasklist_lock);
-		}
-
 		/* Now we don't run again until woken by SIGCONT or SIGKILL */
 		cgroup_enter_frozen();
 		freezable_schedule();
@@ -2465,8 +2582,11 @@ static bool do_signal_stop(int signr)
 		 * Schedule it and let the caller deal with it.
 		 */
 		task_set_jobctl_pending(current, JOBCTL_TRAP_STOP);
-		return false;
 	}
+out:
+	unlock_parents_siglocks(false);
+	spin_unlock_irq(&current->sighand->siglock);
+	return true;
 }
 
 /**
@@ -2624,32 +2744,30 @@ bool get_signal(struct ksignal *ksig)
 	if (unlikely(signal->flags & SIGNAL_CLD_MASK)) {
 		int why;
 
-		if (signal->flags & SIGNAL_CLD_CONTINUED)
-			why = CLD_CONTINUED;
-		else
-			why = CLD_STOPPED;
+		lock_parents_siglocks(true);
+		/* Recheck signal->flags after unlock+lock of siglock */
+		if (likely(signal->flags & SIGNAL_CLD_MASK)) {
+			if (signal->flags & SIGNAL_CLD_CONTINUED)
+				why = CLD_CONTINUED;
+			else
+				why = CLD_STOPPED;
 
-		signal->flags &= ~SIGNAL_CLD_MASK;
+			signal->flags &= ~SIGNAL_CLD_MASK;
 
-		spin_unlock_irq(&sighand->siglock);
-
-		/*
-		 * Notify the parent that we're continuing.  This event is
-		 * always per-process and doesn't make whole lot of sense
-		 * for ptracers, who shouldn't consume the state via
-		 * wait(2) either, but, for backward compatibility, notify
-		 * the ptracer of the group leader too unless it's gonna be
-		 * a duplicate.
-		 */
-		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(current, false, why);
-
-		if (ptrace_reparented(current->group_leader))
-			do_notify_parent_cldstop(current->group_leader,
-						true, why);
-		read_unlock(&tasklist_lock);
-
-		goto relock;
+			/*
+			 * Notify the parent that we're continuing.  This event is
+			 * always per-process and doesn't make whole lot of sense
+			 * for ptracers, who shouldn't consume the state via
+			 * wait(2) either, but, for backward compatibility, notify
+			 * the ptracer of the group leader too unless it's gonna be
+			 * a duplicate.
+			 */
+			do_notify_parent_cldstop(current, false, why);
+			if (ptrace_reparented(current->group_leader))
+				do_notify_parent_cldstop(current->group_leader,
+							 true, why);
+		}
+		unlock_parents_siglocks(true);
 	}
 
 	for (;;) {
@@ -2906,7 +3024,6 @@ static void retarget_shared_pending(struct task_struct *tsk, sigset_t *which)
 
 void exit_signals(struct task_struct *tsk)
 {
-	int group_stop = 0;
 	sigset_t unblocked;
 
 	/*
@@ -2937,21 +3054,20 @@ void exit_signals(struct task_struct *tsk)
 	signotset(&unblocked);
 	retarget_shared_pending(tsk, &unblocked);
 
-	if (unlikely(tsk->jobctl & JOBCTL_STOP_PENDING) &&
-	    task_participate_group_stop(tsk))
-		group_stop = CLD_STOPPED;
-out:
-	spin_unlock_irq(&tsk->sighand->siglock);
-
 	/*
 	 * If group stop has completed, deliver the notification.  This
 	 * should always go to the real parent of the group leader.
 	 */
-	if (unlikely(group_stop)) {
-		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(tsk, false, group_stop);
-		read_unlock(&tasklist_lock);
+	if (unlikely(tsk->jobctl & JOBCTL_STOP_PENDING)) {
+		lock_parents_siglocks(false);
+		/* Recheck JOBCTL_STOP_PENDING after unlock+lock of siglock */
+		if ((tsk->jobctl & JOBCTL_STOP_PENDING) &&
+		    task_participate_group_stop(tsk))
+			do_notify_parent_cldstop(tsk, false, CLD_STOPPED);
+		unlock_parents_siglocks(false);
 	}
+out:
+	spin_unlock_irq(&tsk->sighand->siglock);
 }
 
 /*
-- 
2.35.3


_______________________________________________
linux-um mailing list
linux-um@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-um


WARNING: multiple messages have this Message-ID (diff)
From: "Eric W. Biederman" <ebiederm@xmission.com>
To: linux-kernel@vger.kernel.org
Cc: rjw@rjwysocki.net, Oleg Nesterov <oleg@redhat.com>,
	mingo@kernel.org, vincent.guittot@linaro.org,
	dietmar.eggemann@arm.com, rostedt@goodmis.org, mgorman@suse.de,
	bigeasy@linutronix.de, Will Deacon <will@kernel.org>,
	tj@kernel.org, linux-pm@vger.kernel.org,
	Peter Zijlstra <peterz@infradead.org>,
	Richard Weinberger <richard@nod.at>,
	Anton Ivanov <anton.ivanov@cambridgegreys.com>,
	Johannes Berg <johannes@sipsolutions.net>,
	linux-um@lists.infradead.org, Chris Zankel <chris@zankel.net>,
	Max Filippov <jcmvbkbc@gmail.com>,
	linux-xtensa@linux-xtensa.org, Kees Cook <keescook@chromium.org>,
	Jann Horn <jannh@google.com>,
	linux-ia64@vger.kernel.org, Robert OCallahan <roc@pernos.co>,
	Kyle Huey <khuey@pernos.co>, Richard Henderson <rth@twiddle.net>,
	Ivan Kokshaysky <ink@jurassic.park.msu.ru>,
	Matt Turner <mattst88@gmail.com>,
	Jason Wessel <jason.wessel@windriver.com>,
	Daniel Thompson <daniel.thompson@linaro.org>,
	Douglas Anderson <dianders@chromium.org>,
	Douglas Miller <dougmill@linux.vnet.ibm.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: [PATCH 16/16] signal: Always call do_notify_parent_cldstop with siglock held
Date: Wed, 18 May 2022 22:53:55 +0000	[thread overview]
Message-ID: <20220518225355.784371-16-ebiederm@xmission.com> (raw)
In-Reply-To: <871qwq5ucx.fsf_-_@email.froward.int.ebiederm.org>

Now that siglock keeps tsk->parent and tsk->real_parent constant
require that do_notify_parent_cldstop is called with tsk->siglock held
instead of the tasklist_lock.

As all of the callers of do_notify_parent_cldstop had to drop the
siglock and take tasklist_lock this simplifies all of it's callers.

This removes one reason for taking tasklist_lock.

This makes ptrace_stop so that it should reliably work correctly and
reliably with PREEMPT_RT enabled and CONFIG_CGROUPS disabled.  The
remaining challenge is that cgroup_enter_frozen takes spin_lock after
__state has been set to TASK_TRACED.  Which on PREEMPT_RT means the
code can sleep and change __state.  Not only that but it means that
wait_task_inactive could potentially detect the code scheduling away
at that point and fail, causing ptrace_check_attach to fail.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 kernel/signal.c | 262 ++++++++++++++++++++++++++++++++++--------------
 1 file changed, 189 insertions(+), 73 deletions(-)

diff --git a/kernel/signal.c b/kernel/signal.c
index 2cc45e8448e2..d4956be51939 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1994,6 +1994,129 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)
 	return ret;
 }
 
+/**
+ * lock_parents_siglocks - Take current, real_parent, and parent's siglock
+ * @lock_tracer: The tracers siglock is needed.
+ *
+ * There is no natural ordering to these locks so they must be sorted
+ * before being taken.
+ *
+ * There are two complicating factors here:
+ * - The locks live in sighand and sighand can be arbitrarily shared
+ * - parent and real_parent can change when current's siglock is unlocked.
+ *
+ * To deal with this first the all of the sighand pointers are
+ * gathered under current's siglock, and the sighand pointers are
+ * sorted.  As siglock lives inside of sighand this also sorts the
+ * siglock's by address.
+ *
+ * Then the siglocks are taken in order dropping current's siglock if
+ * necessary.
+ *
+ * Finally if parent and real_parent have not changed return.
+ * If they either parent has changed drop their locks and try again.
+ *
+ * Changing sighand is an infrequent and somewhat expensive operation
+ * (unshare or exec) and so even in the worst case this loop
+ * should not loop too many times before all of the proper locks are
+ * taken in order.
+ *
+ * CONTEXT:
+ * Must be called with @current->sighand->siglock held
+ *
+ * RETURNS:
+ * current's, real_parent's, and parent's siglock held.
+ */
+static void lock_parents_siglocks(bool lock_tracer)
+	__releases(&current->sighand->siglock)
+	__acquires(&current->sighand->siglock)
+	__acquires(&current->real_parent->sighand->siglock)
+	__acquires(&current->parent->sighand->siglock)
+{
+	struct task_struct *me = current;
+	struct sighand_struct *m_sighand = me->sighand;
+
+	lockdep_assert_held(&m_sighand->siglock);
+
+	rcu_read_lock();
+	for (;;) {
+		struct task_struct *parent, *tracer;
+		struct sighand_struct *p_sighand, *t_sighand, *s1, *s2, *s3;
+
+		parent = me->real_parent;
+		tracer = ptrace_parent(me);
+		if (!tracer || !lock_tracer)
+			tracer = parent;
+
+		p_sighand = rcu_dereference(parent->sighand);
+		t_sighand = rcu_dereference(tracer->sighand);
+
+		/* Sort the sighands so that s1 >= s2 >= s3 */
+		s1 = m_sighand;
+		s2 = p_sighand;
+		s3 = t_sighand;
+		if (s1 > s2)
+			swap(s1, s2);
+		if (s1 > s3)
+			swap(s1, s3);
+		if (s2 > s3)
+			swap(s2, s3);
+
+		/* Take the locks in order */
+		if (s1 != m_sighand) {
+			spin_unlock(&m_sighand->siglock);
+			spin_lock(&s1->siglock);
+		}
+		if (s1 != s2)
+			spin_lock_nested(&s2->siglock, 1);
+		if (s2 != s3)
+			spin_lock_nested(&s3->siglock, 2);
+
+		/* Verify the proper locks are held */
+		if (likely((s1 = m_sighand) ||
+			   ((me->real_parent = parent) &&
+			    (me->parent = tracer) &&
+			    (parent->sighand = p_sighand) &&
+			    (tracer->sighand = t_sighand)))) {
+			break;
+		}
+
+		/* Drop all but current's siglock */
+		if (p_sighand != m_sighand)
+			spin_unlock(&p_sighand->siglock);
+		if (t_sighand != p_sighand)
+			spin_unlock(&t_sighand->siglock);
+
+		/*
+		 * Since [pt]_sighand will likely change if we go
+		 * around, and m_sighand is the only one held, make sure
+		 * it is subclass-0, since the above 's1 != m_sighand'
+		 * clause very much relies on that.
+		 */
+		lock_set_subclass(&m_sighand->siglock.dep_map, 0, _RET_IP_);
+	}
+	rcu_read_unlock();
+}
+
+static void unlock_parents_siglocks(bool unlock_tracer)
+	__releases(&current->real_parent->sighand->siglock)
+	__releases(&current->parent->sighand->siglock)
+{
+	struct task_struct *me = current;
+	struct task_struct *parent = me->real_parent;
+	struct task_struct *tracer = ptrace_parent(me);
+	struct sighand_struct *m_sighand = me->sighand;
+	struct sighand_struct *p_sighand = parent->sighand;
+
+	if (p_sighand != m_sighand)
+		spin_unlock(&p_sighand->siglock);
+	if (tracer && unlock_tracer) {
+		struct sighand_struct *t_sighand = tracer->sighand;
+		if (t_sighand != p_sighand)
+			spin_unlock(&t_sighand->siglock);
+	}
+}
+
 static void do_notify_pidfd(struct task_struct *task)
 {
 	struct pid *pid;
@@ -2125,11 +2248,12 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 				     bool for_ptracer, int why)
 {
 	struct kernel_siginfo info;
-	unsigned long flags;
 	struct task_struct *parent;
 	struct sighand_struct *sighand;
 	u64 utime, stime;
 
+	lockdep_assert_held(&tsk->sighand->siglock);
+
 	if (for_ptracer) {
 		parent = tsk->parent;
 	} else {
@@ -2137,6 +2261,8 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 		parent = tsk->real_parent;
 	}
 
+	lockdep_assert_held(&parent->sighand->siglock);
+
 	clear_siginfo(&info);
 	info.si_signo = SIGCHLD;
 	info.si_errno = 0;
@@ -2168,7 +2294,6 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
  	}
 
 	sighand = parent->sighand;
-	spin_lock_irqsave(&sighand->siglock, flags);
 	if (sighand->action[SIGCHLD-1].sa.sa_handler != SIG_IGN &&
 	    !(sighand->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 		send_signal_locked(SIGCHLD, &info, parent, PIDTYPE_TGID);
@@ -2176,7 +2301,6 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
 	 * Even if SIGCHLD is not generated, we must wake up wait4 calls.
 	 */
 	__wake_up_parent(tsk, parent);
-	spin_unlock_irqrestore(&sighand->siglock, flags);
 }
 
 /*
@@ -2208,14 +2332,18 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 		spin_lock_irq(&current->sighand->siglock);
 	}
 
+	lock_parents_siglocks(true);
 	/*
 	 * After this point ptrace_signal_wake_up or signal_wake_up
 	 * will clear TASK_TRACED if ptrace_unlink happens or a fatal
 	 * signal comes in.  Handle previous ptrace_unlinks and fatal
 	 * signals here to prevent ptrace_stop sleeping in schedule.
 	 */
-	if (!current->ptrace || __fatal_signal_pending(current))
+
+	if (!current->ptrace || __fatal_signal_pending(current)) {
+		unlock_parents_siglocks(true);
 		return;
+	}
 
 	set_special_state(TASK_TRACED);
 	current->jobctl |= JOBCTL_TRACED;
@@ -2254,16 +2382,6 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 	if (why = CLD_STOPPED && (current->jobctl & JOBCTL_STOP_PENDING))
 		gstop_done = task_participate_group_stop(current);
 
-	/* any trap clears pending STOP trap, STOP trap clears NOTIFY */
-	task_clear_jobctl_pending(current, JOBCTL_TRAP_STOP);
-	if (info && info->si_code >> 8 = PTRACE_EVENT_STOP)
-		task_clear_jobctl_pending(current, JOBCTL_TRAP_NOTIFY);
-
-	/* entering a trap, clear TRAPPING */
-	task_clear_jobctl_trapping(current);
-
-	spin_unlock_irq(&current->sighand->siglock);
-	read_lock(&tasklist_lock);
 	/*
 	 * Notify parents of the stop.
 	 *
@@ -2279,14 +2397,25 @@ static void ptrace_stop(int exit_code, int why, unsigned long message,
 	if (gstop_done && (!current->ptrace || ptrace_reparented(current)))
 		do_notify_parent_cldstop(current, false, why);
 
+	unlock_parents_siglocks(true);
+
+	/* any trap clears pending STOP trap, STOP trap clears NOTIFY */
+	task_clear_jobctl_pending(current, JOBCTL_TRAP_STOP);
+	if (info && info->si_code >> 8 = PTRACE_EVENT_STOP)
+		task_clear_jobctl_pending(current, JOBCTL_TRAP_NOTIFY);
+
+	/* entering a trap, clear TRAPPING */
+	task_clear_jobctl_trapping(current);
+
 	/*
 	 * Don't want to allow preemption here, because
 	 * sys_ptrace() needs this task to be inactive.
 	 *
-	 * XXX: implement read_unlock_no_resched().
+	 * XXX: implement spin_unlock_no_resched().
 	 */
 	preempt_disable();
-	read_unlock(&tasklist_lock);
+	spin_unlock_irq(&current->sighand->siglock);
+
 	cgroup_enter_frozen();
 	preempt_enable_no_resched();
 	freezable_schedule();
@@ -2361,8 +2490,8 @@ int ptrace_notify(int exit_code, unsigned long message)
  * on %true return.
  *
  * RETURNS:
- * %false if group stop is already cancelled or ptrace trap is scheduled.
- * %true if participated in group stop.
+ * %false if group stop is already cancelled.
+ * %true otherwise (as lock_parents_siglocks may have dropped siglock).
  */
 static bool do_signal_stop(int signr)
 	__releases(&current->sighand->siglock)
@@ -2425,36 +2554,24 @@ static bool do_signal_stop(int signr)
 		}
 	}
 
+	lock_parents_siglocks(false);
+	/* Recheck JOBCTL_STOP_PENDING after unlock+lock of siglock */
+	if (unlikely(!(current->jobctl & JOBCTL_STOP_PENDING)))
+		goto out;
 	if (likely(!current->ptrace)) {
-		int notify = 0;
-
 		/*
 		 * If there are no other threads in the group, or if there
 		 * is a group stop in progress and we are the last to stop,
-		 * report to the parent.
+		 * report to the real_parent.
 		 */
 		if (task_participate_group_stop(current))
-			notify = CLD_STOPPED;
+			do_notify_parent_cldstop(current, false, CLD_STOPPED);
+		unlock_parents_siglocks(false);
 
 		current->jobctl |= JOBCTL_STOPPED;
 		set_special_state(TASK_STOPPED);
 		spin_unlock_irq(&current->sighand->siglock);
 
-		/*
-		 * Notify the parent of the group stop completion.  Because
-		 * we're not holding either the siglock or tasklist_lock
-		 * here, ptracer may attach inbetween; however, this is for
-		 * group stop and should always be delivered to the real
-		 * parent of the group leader.  The new ptracer will get
-		 * its notification when this task transitions into
-		 * TASK_TRACED.
-		 */
-		if (notify) {
-			read_lock(&tasklist_lock);
-			do_notify_parent_cldstop(current, false, notify);
-			read_unlock(&tasklist_lock);
-		}
-
 		/* Now we don't run again until woken by SIGCONT or SIGKILL */
 		cgroup_enter_frozen();
 		freezable_schedule();
@@ -2465,8 +2582,11 @@ static bool do_signal_stop(int signr)
 		 * Schedule it and let the caller deal with it.
 		 */
 		task_set_jobctl_pending(current, JOBCTL_TRAP_STOP);
-		return false;
 	}
+out:
+	unlock_parents_siglocks(false);
+	spin_unlock_irq(&current->sighand->siglock);
+	return true;
 }
 
 /**
@@ -2624,32 +2744,30 @@ bool get_signal(struct ksignal *ksig)
 	if (unlikely(signal->flags & SIGNAL_CLD_MASK)) {
 		int why;
 
-		if (signal->flags & SIGNAL_CLD_CONTINUED)
-			why = CLD_CONTINUED;
-		else
-			why = CLD_STOPPED;
+		lock_parents_siglocks(true);
+		/* Recheck signal->flags after unlock+lock of siglock */
+		if (likely(signal->flags & SIGNAL_CLD_MASK)) {
+			if (signal->flags & SIGNAL_CLD_CONTINUED)
+				why = CLD_CONTINUED;
+			else
+				why = CLD_STOPPED;
 
-		signal->flags &= ~SIGNAL_CLD_MASK;
+			signal->flags &= ~SIGNAL_CLD_MASK;
 
-		spin_unlock_irq(&sighand->siglock);
-
-		/*
-		 * Notify the parent that we're continuing.  This event is
-		 * always per-process and doesn't make whole lot of sense
-		 * for ptracers, who shouldn't consume the state via
-		 * wait(2) either, but, for backward compatibility, notify
-		 * the ptracer of the group leader too unless it's gonna be
-		 * a duplicate.
-		 */
-		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(current, false, why);
-
-		if (ptrace_reparented(current->group_leader))
-			do_notify_parent_cldstop(current->group_leader,
-						true, why);
-		read_unlock(&tasklist_lock);
-
-		goto relock;
+			/*
+			 * Notify the parent that we're continuing.  This event is
+			 * always per-process and doesn't make whole lot of sense
+			 * for ptracers, who shouldn't consume the state via
+			 * wait(2) either, but, for backward compatibility, notify
+			 * the ptracer of the group leader too unless it's gonna be
+			 * a duplicate.
+			 */
+			do_notify_parent_cldstop(current, false, why);
+			if (ptrace_reparented(current->group_leader))
+				do_notify_parent_cldstop(current->group_leader,
+							 true, why);
+		}
+		unlock_parents_siglocks(true);
 	}
 
 	for (;;) {
@@ -2906,7 +3024,6 @@ static void retarget_shared_pending(struct task_struct *tsk, sigset_t *which)
 
 void exit_signals(struct task_struct *tsk)
 {
-	int group_stop = 0;
 	sigset_t unblocked;
 
 	/*
@@ -2937,21 +3054,20 @@ void exit_signals(struct task_struct *tsk)
 	signotset(&unblocked);
 	retarget_shared_pending(tsk, &unblocked);
 
-	if (unlikely(tsk->jobctl & JOBCTL_STOP_PENDING) &&
-	    task_participate_group_stop(tsk))
-		group_stop = CLD_STOPPED;
-out:
-	spin_unlock_irq(&tsk->sighand->siglock);
-
 	/*
 	 * If group stop has completed, deliver the notification.  This
 	 * should always go to the real parent of the group leader.
 	 */
-	if (unlikely(group_stop)) {
-		read_lock(&tasklist_lock);
-		do_notify_parent_cldstop(tsk, false, group_stop);
-		read_unlock(&tasklist_lock);
+	if (unlikely(tsk->jobctl & JOBCTL_STOP_PENDING)) {
+		lock_parents_siglocks(false);
+		/* Recheck JOBCTL_STOP_PENDING after unlock+lock of siglock */
+		if ((tsk->jobctl & JOBCTL_STOP_PENDING) &&
+		    task_participate_group_stop(tsk))
+			do_notify_parent_cldstop(tsk, false, CLD_STOPPED);
+		unlock_parents_siglocks(false);
 	}
+out:
+	spin_unlock_irq(&tsk->sighand->siglock);
 }
 
 /*
-- 
2.35.3

  parent reply	other threads:[~2022-05-18 22:56 UTC|newest]

Thread overview: 572+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-21 15:02 [PATCH v2 0/5] ptrace-vs-PREEMPT_RT and freezer rewrite Peter Zijlstra
2022-04-21 15:02 ` [PATCH v2 1/5] sched,signal,ptrace: Rework TASK_TRACED, TASK_STOPPED state Peter Zijlstra
2022-04-26 23:34   ` Eric W. Biederman
2022-04-28 10:00     ` Peter Zijlstra
2022-04-21 15:02 ` [PATCH v2 2/5] sched,ptrace: Fix ptrace_check_attach() vs PREEMPT_RT Peter Zijlstra
2022-04-21 18:23   ` Oleg Nesterov
2022-04-21 19:58     ` Peter Zijlstra
2022-04-21 18:40   ` Eric W. Biederman
2022-04-26 22:50     ` [PATCH 0/9] ptrace: cleaning up ptrace_stop Eric W. Biederman
2022-04-26 22:50       ` Eric W. Biederman
2022-04-26 22:52       ` [PATCH 1/9] signal: Rename send_signal send_signal_locked Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-28 10:27         ` Peter Zijlstra
2022-04-28 10:27           ` Peter Zijlstra
2022-04-26 22:52       ` [PATCH 2/9] signal: Replace __group_send_sig_info with send_signal_locked Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-26 22:52       ` [PATCH 3/9] ptrace/um: Replace PT_DTRACE with TIF_SINGLESTEP Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-27  7:10         ` Johannes Berg
2022-04-27  7:10           ` Johannes Berg
2022-04-27 13:50           ` Eric W. Biederman
2022-04-27 13:50             ` Eric W. Biederman
2022-04-26 22:52       ` [PATCH 4/9] ptrace/xtensa: Replace PT_SINGLESTEP " Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-26 23:33         ` Max Filippov
2022-04-26 23:33           ` Max Filippov
2022-04-26 22:52       ` [PATCH 5/9] signal: Protect parent child relationships by childs siglock Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-27  6:40         ` Sebastian Andrzej Siewior
2022-04-27  6:40           ` Sebastian Andrzej Siewior
2022-04-27 13:35           ` Eric W. Biederman
2022-04-27 13:35             ` Eric W. Biederman
2022-04-26 22:52       ` [PATCH 6/9] signal: Always call do_notify_parent_cldstop with siglock held Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-27 14:10         ` Oleg Nesterov
2022-04-27 14:10           ` Oleg Nesterov
2022-04-27 14:20           ` Eric W. Biederman
2022-04-27 14:20             ` Eric W. Biederman
2022-04-27 14:43             ` Oleg Nesterov
2022-04-27 14:43               ` Oleg Nesterov
2022-04-27 14:47             ` Eric W. Biederman
2022-04-27 14:47               ` Eric W. Biederman
2022-04-28 17:44               ` Peter Zijlstra
2022-04-28 17:44                 ` Peter Zijlstra
2022-04-28 18:22                 ` Oleg Nesterov
2022-04-28 18:22                   ` Oleg Nesterov
2022-04-28 18:37                 ` Eric W. Biederman
2022-04-28 18:37                   ` Eric W. Biederman
2022-04-28 20:49                   ` Eric W. Biederman
2022-04-28 20:49                     ` Eric W. Biederman
2022-04-28 22:19                     ` Peter Zijlstra
2022-04-28 22:19                       ` Peter Zijlstra
2022-04-27 14:56         ` Oleg Nesterov
2022-04-27 14:56           ` Oleg Nesterov
2022-04-27 15:00           ` Oleg Nesterov
2022-04-27 15:00             ` Oleg Nesterov
2022-04-27 21:52             ` Eric W. Biederman
2022-04-27 21:52               ` Eric W. Biederman
2022-04-28 10:38         ` Peter Zijlstra
2022-04-28 10:38           ` Peter Zijlstra
2022-04-26 22:52       ` [PATCH 7/9] ptrace: Simplify the wait_task_inactive call in ptrace_check_attach Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-27 13:42         ` Eric W. Biederman
2022-04-27 13:42           ` Eric W. Biederman
2022-04-27 14:27           ` Eric W. Biederman
2022-04-27 14:27             ` Eric W. Biederman
2022-04-27 15:14         ` Oleg Nesterov
2022-04-27 15:14           ` Oleg Nesterov
2022-04-28 10:42           ` Peter Zijlstra
2022-04-28 10:42             ` Peter Zijlstra
2022-04-28 11:19             ` Oleg Nesterov
2022-04-28 11:19               ` Oleg Nesterov
2022-04-28 13:54               ` Peter Zijlstra
2022-04-28 13:54                 ` Peter Zijlstra
2022-04-28 14:57                 ` Oleg Nesterov
2022-04-28 14:57                   ` Oleg Nesterov
2022-04-28 16:09                   ` Peter Zijlstra
2022-04-28 16:09                     ` Peter Zijlstra
2022-04-28 16:19                     ` Oleg Nesterov
2022-04-28 16:19                       ` Oleg Nesterov
2022-04-26 22:52       ` [PATCH 8/9] ptrace: Use siglock instead of tasklist_lock " Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-27 15:20         ` Oleg Nesterov
2022-04-27 15:20           ` Oleg Nesterov
2022-04-26 22:52       ` [PATCH 9/9] ptrace: Don't change __state Eric W. Biederman
2022-04-26 22:52         ` Eric W. Biederman
2022-04-27 15:41         ` Oleg Nesterov
2022-04-27 15:41           ` Oleg Nesterov
2022-04-27 22:35           ` Eric W. Biederman
2022-04-27 22:35             ` Eric W. Biederman
2022-04-27 16:09         ` Oleg Nesterov
2022-04-27 16:33           ` Eric W. Biederman
2022-04-27 17:18             ` Oleg Nesterov
2022-04-27 17:18               ` Oleg Nesterov
2022-04-27 17:21               ` Oleg Nesterov
2022-04-27 17:21                 ` Oleg Nesterov
2022-04-27 17:31                 ` Eric W. Biederman
2022-04-27 17:31                   ` Eric W. Biederman
2022-04-27 23:05         ` Eric W. Biederman
2022-04-27 23:05           ` Eric W. Biederman
2022-04-28 15:11           ` Oleg Nesterov
2022-04-28 15:11             ` Oleg Nesterov
2022-04-28 16:50             ` Eric W. Biederman
2022-04-28 16:50               ` Eric W. Biederman
2022-04-28 18:53               ` Oleg Nesterov
2022-04-28 18:53                 ` Oleg Nesterov
2022-04-28 10:07       ` [PATCH 0/9] ptrace: cleaning up ptrace_stop Peter Zijlstra
2022-04-28 10:07         ` Peter Zijlstra
2022-04-29 21:46       ` [PATCH 0/12] " Eric W. Biederman
2022-04-29 21:46         ` Eric W. Biederman
2022-04-29 21:46         ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 01/12] signal: Rename send_signal send_signal_locked Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-05-02  7:50           ` Sebastian Andrzej Siewior
2022-05-02  7:50             ` Sebastian Andrzej Siewior
2022-05-02  7:50             ` Sebastian Andrzej Siewior
2022-04-29 21:48         ` [PATCH v2 02/12] signal: Replace __group_send_sig_info with send_signal_locked Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-05-02  7:58           ` Sebastian Andrzej Siewior
2022-05-02  7:58             ` Sebastian Andrzej Siewior
2022-05-02  7:58             ` Sebastian Andrzej Siewior
2022-04-29 21:48         ` [PATCH v2 03/12] ptrace/um: Replace PT_DTRACE with TIF_SINGLESTEP Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 04/12] ptrace/xtensa: Replace PT_SINGLESTEP " Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 05/12] signal: Use lockdep_assert_held instead of assert_spin_locked Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 06/12] ptrace: Reimplement PTRACE_KILL by always sending SIGKILL Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-05-02 14:37           ` Oleg Nesterov
2022-05-02 14:37             ` Oleg Nesterov
2022-05-02 14:37             ` Oleg Nesterov
2022-05-03 19:36             ` Eric W. Biederman
2022-05-03 19:36               ` Eric W. Biederman
2022-05-03 19:36               ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 07/12] ptrace: Don't change __state Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 22:27           ` Peter Zijlstra
2022-04-29 22:27             ` Peter Zijlstra
2022-04-29 22:27             ` Peter Zijlstra
2022-05-02  8:59           ` Sebastian Andrzej Siewior
2022-05-02  8:59             ` Sebastian Andrzej Siewior
2022-05-02  8:59             ` Sebastian Andrzej Siewior
2022-05-02 15:39           ` Oleg Nesterov
2022-05-02 15:39             ` Oleg Nesterov
2022-05-02 15:39             ` Oleg Nesterov
2022-05-02 16:35             ` Eric W. Biederman
2022-05-02 16:35               ` Eric W. Biederman
2022-05-02 16:35               ` Eric W. Biederman
2022-05-03 13:41               ` Oleg Nesterov
2022-05-03 13:41                 ` Oleg Nesterov
2022-05-03 13:41                 ` Oleg Nesterov
2022-05-03 20:45                 ` Eric W. Biederman
2022-05-03 20:45                   ` Eric W. Biederman
2022-05-03 20:45                   ` Eric W. Biederman
2022-05-04 14:02                   ` Oleg Nesterov
2022-05-04 14:02                     ` Oleg Nesterov
2022-05-04 14:02                     ` Oleg Nesterov
2022-05-04 17:37                     ` Eric W. Biederman
2022-05-04 17:37                       ` Eric W. Biederman
2022-05-04 17:37                       ` Eric W. Biederman
2022-05-04 18:28                       ` Eric W. Biederman
2022-05-04 18:28                         ` Eric W. Biederman
2022-05-04 18:28                         ` Eric W. Biederman
2022-05-02 15:47           ` Oleg Nesterov
2022-05-02 15:47             ` Oleg Nesterov
2022-05-02 15:47             ` Oleg Nesterov
2022-04-29 21:48         ` [PATCH v2 08/12] ptrace: Remove arch_ptrace_attach Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 09/12] ptrace: Always take siglock in ptrace_resume Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 10/12] ptrace: Only return signr from ptrace_stop if it was provided Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-05-02 10:08           ` Sebastian Andrzej Siewior
2022-05-02 10:08             ` Sebastian Andrzej Siewior
2022-05-02 10:08             ` Sebastian Andrzej Siewior
2022-04-29 21:48         ` [PATCH v2 11/12] ptrace: Always call schedule in ptrace_stop Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48         ` [PATCH v2 12/12] sched,signal,ptrace: Rework TASK_TRACED, TASK_STOPPED state Eric W. Biederman
2022-04-29 21:48           ` Eric W. Biederman
2022-04-29 21:48           ` [PATCH v2 12/12] sched, signal, ptrace: " Eric W. Biederman
2022-05-02 10:18           ` [PATCH v2 12/12] sched,signal,ptrace: " Sebastian Andrzej Siewior
2022-05-02 10:18             ` Sebastian Andrzej Siewior
2022-05-02 10:18             ` Sebastian Andrzej Siewior
2022-05-02 13:38         ` [PATCH 0/12] ptrace: cleaning up ptrace_stop Sebastian Andrzej Siewior
2022-05-02 13:38           ` Sebastian Andrzej Siewior
2022-05-02 13:38           ` Sebastian Andrzej Siewior
2022-05-04 22:39         ` [PATCH v3 0/11] " Eric W. Biederman
2022-05-04 22:39           ` Eric W. Biederman
2022-05-04 22:39           ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 01/11] signal: Rename send_signal send_signal_locked Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 02/11] signal: Replace __group_send_sig_info with send_signal_locked Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 03/11] ptrace/um: Replace PT_DTRACE with TIF_SINGLESTEP Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 04/11] ptrace/xtensa: Replace PT_SINGLESTEP " Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 05/11] ptrace: Remove arch_ptrace_attach Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 06/11] signal: Use lockdep_assert_held instead of assert_spin_locked Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 07/11] ptrace: Reimplement PTRACE_KILL by always sending SIGKILL Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 08/11] ptrace: Admit ptrace_stop can generate spuriuos SIGTRAPs Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-05 14:57             ` Oleg Nesterov
2022-05-05 14:57               ` Oleg Nesterov
2022-05-05 14:57               ` Oleg Nesterov
2022-05-05 16:59               ` Eric W. Biederman
2022-05-05 16:59                 ` Eric W. Biederman
2022-05-05 16:59                 ` Eric W. Biederman
2022-05-05 15:01             ` Oleg Nesterov
2022-05-05 15:01               ` Oleg Nesterov
2022-05-05 15:01               ` Oleg Nesterov
2022-05-05 17:21               ` Eric W. Biederman
2022-05-05 17:21                 ` Eric W. Biederman
2022-05-05 17:21                 ` Eric W. Biederman
2022-05-05 17:27                 ` Oleg Nesterov
2022-05-05 17:27                   ` Oleg Nesterov
2022-05-05 17:27                   ` Oleg Nesterov
2022-05-05 15:28             ` Oleg Nesterov
2022-05-05 15:28               ` Oleg Nesterov
2022-05-05 15:28               ` Oleg Nesterov
2022-05-05 17:53               ` Eric W. Biederman
2022-05-05 17:53                 ` Eric W. Biederman
2022-05-05 17:53                 ` Eric W. Biederman
2022-05-05 18:10                 ` Oleg Nesterov
2022-05-05 18:10                   ` Oleg Nesterov
2022-05-05 18:10                   ` Oleg Nesterov
2022-05-04 22:40           ` [PATCH v3 09/11] ptrace: Don't change __state Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-05 12:50             ` Sebastian Andrzej Siewior
2022-05-05 12:50               ` Sebastian Andrzej Siewior
2022-05-05 12:50               ` Sebastian Andrzej Siewior
2022-05-05 16:48               ` Eric W. Biederman
2022-05-05 16:48                 ` Eric W. Biederman
2022-05-05 16:48                 ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 10/11] ptrace: Always take siglock in ptrace_resume Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40           ` [PATCH v3 11/11] sched,signal,ptrace: Rework TASK_TRACED, TASK_STOPPED state Eric W. Biederman
2022-05-04 22:40             ` Eric W. Biederman
2022-05-04 22:40             ` [PATCH v3 11/11] sched, signal, ptrace: " Eric W. Biederman
2022-05-05 18:25           ` [PATCH v4 0/12] ptrace: cleaning up ptrace_stop Eric W. Biederman
2022-05-05 18:25             ` Eric W. Biederman
2022-05-05 18:25             ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 01/12] signal: Rename send_signal send_signal_locked Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 02/12] signal: Replace __group_send_sig_info with send_signal_locked Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 03/12] ptrace/um: Replace PT_DTRACE with TIF_SINGLESTEP Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 04/12] ptrace/xtensa: Replace PT_SINGLESTEP " Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 05/12] ptrace: Remove arch_ptrace_attach Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 06/12] signal: Use lockdep_assert_held instead of assert_spin_locked Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 07/12] ptrace: Reimplement PTRACE_KILL by always sending SIGKILL Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 08/12] ptrace: Document that wait_task_inactive can't fail Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-06  6:55               ` Sebastian Andrzej Siewior
2022-05-06  6:55                 ` Sebastian Andrzej Siewior
2022-05-06  6:55                 ` Sebastian Andrzej Siewior
2022-05-05 18:26             ` [PATCH v4 09/12] ptrace: Admit ptrace_stop can generate spuriuos SIGTRAPs Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 10/12] ptrace: Don't change __state Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-06 15:09               ` Oleg Nesterov
2022-05-06 15:09                 ` Oleg Nesterov
2022-05-06 15:09                 ` Oleg Nesterov
2022-05-06 19:42                 ` Eric W. Biederman
2022-05-06 19:42                   ` Eric W. Biederman
2022-05-06 19:42                   ` Eric W. Biederman
2022-05-10 14:23               ` Oleg Nesterov
2022-05-10 14:23                 ` Oleg Nesterov
2022-05-10 14:23                 ` Oleg Nesterov
2022-05-10 15:17                 ` Eric W. Biederman
2022-05-10 15:17                   ` Eric W. Biederman
2022-05-10 15:17                   ` Eric W. Biederman
2022-05-10 15:34                   ` Oleg Nesterov
2022-05-10 15:34                     ` Oleg Nesterov
2022-05-10 15:34                     ` Oleg Nesterov
2022-05-05 18:26             ` [PATCH v4 11/12] ptrace: Always take siglock in ptrace_resume Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26             ` [PATCH v4 12/12] sched,signal,ptrace: Rework TASK_TRACED, TASK_STOPPED state Eric W. Biederman
2022-05-05 18:26               ` Eric W. Biederman
2022-05-05 18:26               ` [PATCH v4 12/12] sched, signal, ptrace: " Eric W. Biederman
2022-06-21 13:00               ` [PATCH v4 12/12] sched,signal,ptrace: " Alexander Gordeev
2022-06-21 13:00                 ` Alexander Gordeev
2022-06-21 13:00                 ` Alexander Gordeev
2022-06-21 14:02                 ` Eric W. Biederman
2022-06-21 14:02                   ` Eric W. Biederman
2022-06-21 15:15                   ` Alexander Gordeev
2022-06-21 15:15                     ` Alexander Gordeev
2022-06-21 15:15                     ` Alexander Gordeev
2022-06-21 17:47                     ` Eric W. Biederman
2022-06-21 17:47                       ` Eric W. Biederman
2022-06-21 17:47                       ` Eric W. Biederman
2022-06-25 16:34                     ` Eric W. Biederman
2022-06-25 16:34                       ` Eric W. Biederman
2022-06-25 16:34                       ` Eric W. Biederman
2022-06-28 18:36                       ` Alexander Gordeev
2022-06-28 18:36                         ` Alexander Gordeev
2022-06-28 18:36                         ` Alexander Gordeev
2022-06-28 22:42                         ` Eric W. Biederman
2022-06-28 22:42                           ` Eric W. Biederman
2022-06-28 22:48                           ` Steven Rostedt
2022-06-28 22:48                             ` Steven Rostedt
2022-06-29  3:39                             ` Eric W. Biederman
2022-06-29  3:39                               ` Eric W. Biederman
2022-06-29  3:39                               ` Eric W. Biederman
2022-06-29 20:25                               ` Alexander Gordeev
2022-06-29 20:25                                 ` Alexander Gordeev
2022-06-29 20:25                                 ` Alexander Gordeev
2022-07-05 15:44                               ` Peter Zijlstra
2022-07-05 15:44                                 ` Peter Zijlstra
2022-07-05 15:44                                 ` Peter Zijlstra
2022-07-06  6:56                                 ` Alexander Gordeev
2022-07-06  6:56                                   ` Alexander Gordeev
2022-07-06  6:56                                   ` Alexander Gordeev
2022-06-28 23:15                     ` Steven Rostedt
2022-06-28 23:15                       ` Steven Rostedt
2022-06-28 23:15                       ` Steven Rostedt
2022-07-05 13:47                       ` Sven Schnelle
2022-07-05 13:47                         ` Sven Schnelle
2022-07-05 13:47                         ` Sven Schnelle
2022-07-05 17:28                         ` Sven Schnelle
2022-07-05 17:28                           ` Sven Schnelle
2022-07-05 17:28                           ` Sven Schnelle
2022-07-05 19:25                           ` Peter Zijlstra
2022-07-05 19:25                             ` Peter Zijlstra
2022-07-05 19:25                             ` Peter Zijlstra
2022-07-06  7:58                             ` Sven Schnelle
2022-07-06  7:58                               ` Sven Schnelle
2022-07-06  7:58                               ` Sven Schnelle
2022-07-06  8:59                               ` Peter Zijlstra
2022-07-06  8:59                                 ` Peter Zijlstra
2022-07-06  8:59                                 ` Peter Zijlstra
2022-07-06  9:27                                 ` Sven Schnelle
2022-07-06  9:27                                   ` Sven Schnelle
2022-07-06  9:27                                   ` Sven Schnelle
2022-07-06 10:11                                   ` Peter Zijlstra
2022-07-06 10:11                                     ` Peter Zijlstra
2022-05-06 14:14             ` [PATCH v4 0/12] ptrace: cleaning up ptrace_stop Oleg Nesterov
2022-05-06 14:14               ` Oleg Nesterov
2022-05-06 14:14               ` Oleg Nesterov
2022-05-06 14:38               ` Eric W. Biederman
2022-05-06 14:38                 ` Eric W. Biederman
2022-05-06 14:38                 ` Eric W. Biederman
2022-05-06 21:26             ` Kees Cook
2022-05-06 21:26               ` Kees Cook
2022-05-06 21:59               ` Eric W. Biederman
2022-05-06 21:59                 ` Eric W. Biederman
2022-05-06 21:59                 ` Eric W. Biederman
2022-05-10 14:11             ` Oleg Nesterov
2022-05-10 14:11               ` Oleg Nesterov
2022-05-10 14:11               ` Oleg Nesterov
2022-05-10 14:26               ` Eric W. Biederman
2022-05-10 14:26                 ` Eric W. Biederman
2022-05-10 14:26                 ` Eric W. Biederman
2022-05-10 14:45                 ` Sebastian Andrzej Siewior
2022-05-10 14:45                   ` Sebastian Andrzej Siewior
2022-05-10 14:45                   ` Sebastian Andrzej Siewior
2022-05-10 15:18                   ` Eric W. Biederman
2022-05-10 15:18                     ` Eric W. Biederman
2022-05-10 15:18                     ` Eric W. Biederman
2022-05-11 20:00                 ` Eric W. Biederman
2022-05-11 20:00                   ` Eric W. Biederman
2022-05-11 20:00                   ` Eric W. Biederman
2022-05-18 22:49             ` [PATCH 00/16] ptrace: cleanups and calling do_cldstop with only siglock Eric W. Biederman
2022-05-18 22:49               ` Eric W. Biederman
2022-05-18 22:49               ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 01/16] signal/alpha: Remove unused definition of TASK_REAL_PARENT Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 02/16] signal/ia64: Remove unused definition of IA64_TASK_REAL_PARENT_OFFSET Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 03/16] kdb: Use real_parent when displaying a list of processes Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-19  7:56                 ` Peter Zijlstra
2022-05-19  7:56                   ` Peter Zijlstra
2022-05-19  7:56                   ` Peter Zijlstra
2022-05-19 18:06                   ` Eric W. Biederman
2022-05-19 18:06                     ` Eric W. Biederman
2022-05-19 18:06                     ` Eric W. Biederman
2022-05-19 20:52                 ` Doug Anderson
2022-05-19 20:52                   ` Doug Anderson
2022-05-19 20:52                   ` Doug Anderson
2022-05-19 23:48                   ` Eric W. Biederman
2022-05-19 23:48                     ` Eric W. Biederman
2022-05-19 23:48                     ` Eric W. Biederman
2022-05-20 23:01                     ` Doug Anderson
2022-05-20 23:01                       ` Doug Anderson
2022-05-20 23:01                       ` Doug Anderson
2022-05-18 22:53               ` [PATCH 04/16] powerpc/xmon: " Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 05/16] ptrace: Remove dead code from __ptrace_detach Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-24 11:42                 ` Oleg Nesterov
2022-05-24 11:42                   ` Oleg Nesterov
2022-05-24 11:42                   ` Oleg Nesterov
2022-05-25 14:33                   ` Oleg Nesterov
2022-05-25 14:33                     ` Oleg Nesterov
2022-05-25 14:33                     ` Oleg Nesterov
2022-06-06 16:06                     ` Eric W. Biederman
2022-06-06 16:06                       ` Eric W. Biederman
2022-06-06 16:06                       ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 06/16] ptrace: Remove unnecessary locking in ptrace_(get|set)siginfo Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-24 13:25                 ` Oleg Nesterov
2022-05-24 13:25                   ` Oleg Nesterov
2022-05-24 13:25                   ` Oleg Nesterov
2022-05-18 22:53               ` [PATCH 07/16] signal: Wake up the designated parent Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-24 13:25                 ` Oleg Nesterov
2022-05-24 13:25                   ` Oleg Nesterov
2022-05-24 13:25                   ` Oleg Nesterov
2022-05-24 16:28                   ` Oleg Nesterov
2022-05-24 16:28                     ` Oleg Nesterov
2022-05-24 16:28                     ` Oleg Nesterov
2022-05-25 14:28                     ` Oleg Nesterov
2022-05-25 14:28                       ` Oleg Nesterov
2022-05-25 14:28                       ` Oleg Nesterov
2022-06-06 22:10                       ` Eric W. Biederman
2022-06-06 22:10                         ` Eric W. Biederman
2022-06-06 22:10                         ` Eric W. Biederman
2022-06-07 15:26                         ` Oleg Nesterov
2022-06-07 15:26                           ` Oleg Nesterov
2022-06-07 15:26                           ` Oleg Nesterov
2022-05-18 22:53               ` [PATCH 08/16] ptrace: Only populate last_siginfo from ptrace Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-24 15:27                 ` Oleg Nesterov
2022-05-24 15:27                   ` Oleg Nesterov
2022-05-24 15:27                   ` Oleg Nesterov
2022-06-06 22:16                   ` Eric W. Biederman
2022-06-06 22:16                     ` Eric W. Biederman
2022-06-06 22:16                     ` Eric W. Biederman
2022-06-07 15:29                     ` Oleg Nesterov
2022-06-07 15:29                       ` Oleg Nesterov
2022-06-07 15:29                       ` Oleg Nesterov
2022-05-18 22:53               ` [PATCH 09/16] ptrace: In ptrace_setsiginfo deal with invalid si_signo Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 10/16] ptrace: In ptrace_signal look at what the debugger did with siginfo Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 11/16] ptrace: Use si_sino as the signal number to resume with Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 12/16] ptrace: Stop protecting ptrace_set_signr with tasklist_lock Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 13/16] ptrace: Document why ptrace_setoptions does not need a lock Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 14/16] signal: Protect parent child relationships by childs siglock Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` [PATCH 15/16] ptrace: Use siglock instead of tasklist_lock in ptrace_check_attach Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-18 22:53               ` Eric W. Biederman [this message]
2022-05-18 22:53                 ` [PATCH 16/16] signal: Always call do_notify_parent_cldstop with siglock held Eric W. Biederman
2022-05-18 22:53                 ` Eric W. Biederman
2022-05-20 16:19                 ` kernel test robot
2022-05-20 16:19                   ` kernel test robot
2022-05-20 16:19                   ` kernel test robot
     [not found]               ` <CALWUPBdFDLuT7JaNGSJ_UXbHf8y9uKdC-SkAqzd=FQC0MX4nNQ@mail.gmail.com>
2022-05-19  6:19                 ` [PATCH 00/16] ptrace: cleanups and calling do_cldstop with only siglock Sebastian Andrzej Siewior
2022-05-19  6:19                   ` Sebastian Andrzej Siewior
2022-05-19  6:19                   ` Sebastian Andrzej Siewior
2022-05-19 18:05                   ` Eric W. Biederman
2022-05-19 18:05                     ` Eric W. Biederman
2022-05-19 18:05                     ` Eric W. Biederman
2022-05-20  5:24                     ` Kyle Huey
2022-05-20  5:24                       ` Kyle Huey
2022-05-20  5:24                       ` Kyle Huey
2022-06-06 16:12                       ` Eric W. Biederman
2022-06-06 16:12                         ` Eric W. Biederman
2022-06-09 19:59                         ` Kyle Huey
2022-06-09 19:59                           ` Kyle Huey
2022-06-09 19:59                           ` Kyle Huey
2022-05-20  7:33               ` Sebastian Andrzej Siewior
2022-05-20  7:33                 ` Sebastian Andrzej Siewior
2022-05-20  7:33                 ` Sebastian Andrzej Siewior
2022-05-20 19:32                 ` Eric W. Biederman
2022-05-20 19:32                   ` Eric W. Biederman
2022-05-20 19:32                   ` Eric W. Biederman
2022-05-20 19:58                   ` Peter Zijlstra
2022-05-20 19:58                     ` Peter Zijlstra
2022-05-20 19:58                     ` Peter Zijlstra
2022-05-20  9:19               ` Sebastian Andrzej Siewior
2022-05-20  9:19                 ` Sebastian Andrzej Siewior
2022-05-20  9:19                 ` Sebastian Andrzej Siewior
2022-06-22 16:43             ` [PATCH 0/3] ptrace: Stop supporting SIGKILL for PTRACE_EVENT_EXIT Eric W. Biederman
2022-06-22 16:45               ` [PATCH 1/3] signal: Ensure SIGNAL_GROUP_EXIT gets set in do_group_exit Eric W. Biederman
2022-06-22 16:46               ` [PATCH 2/3] signal: Guarantee that SIGNAL_GROUP_EXIT is set on process exit Eric W. Biederman
2022-06-23  7:49                 ` kernel test robot
2022-06-22 16:47               ` [PATCH 3/3] signal: Drop signals received after a fatal signal has been processed Eric W. Biederman
2022-06-23 15:12               ` [PATCH 0/3] ptrace: Stop supporting SIGKILL for PTRACE_EVENT_EXIT Alexander Gordeev
2022-06-23 21:55                 ` Eric W. Biederman
2022-07-08 22:25               ` Eric W. Biederman
2022-07-08 23:22                 ` Keno Fischer
2022-07-12 20:03                   ` Eric W. Biederman
2022-07-16 21:29                     ` Eric W. Biederman
2022-07-16 23:21                       ` Kyle Huey
2022-04-25 14:35   ` [PATCH v2 2/5] sched,ptrace: Fix ptrace_check_attach() vs PREEMPT_RT Oleg Nesterov
2022-04-25 18:33     ` Peter Zijlstra
2022-04-26  0:38       ` Eric W. Biederman
2022-04-26  5:51         ` Oleg Nesterov
2022-04-26 17:19           ` Eric W. Biederman
2022-04-26 18:11             ` Oleg Nesterov
2022-04-25 17:47   ` Oleg Nesterov
2022-04-27  0:24     ` Eric W. Biederman
2022-04-28 20:29       ` Peter Zijlstra
2022-04-28 20:59         ` Oleg Nesterov
2022-04-28 22:21           ` Peter Zijlstra
2022-04-28 22:50             ` Oleg Nesterov
2022-04-27 15:53   ` Oleg Nesterov
2022-04-27 21:57     ` Eric W. Biederman
2022-04-21 15:02 ` [PATCH v2 3/5] freezer: Have {,un}lock_system_sleep() save/restore flags Peter Zijlstra
2022-04-21 15:02 ` [PATCH v2 4/5] freezer,umh: Clean up freezer/initrd interaction Peter Zijlstra
2022-04-21 15:02 ` [PATCH v2 5/5] freezer,sched: Rewrite core freezer logic Peter Zijlstra
2022-04-21 17:26   ` Eric W. Biederman
2022-04-21 17:57     ` Oleg Nesterov
2022-04-21 19:55     ` Peter Zijlstra
2022-04-21 20:07       ` Peter Zijlstra
2022-04-22 15:52         ` Eric W. Biederman
2022-04-22 17:43 ` [PATCH v2 0/5] ptrace-vs-PREEMPT_RT and freezer rewrite Sebastian Andrzej Siewior
2022-04-22 19:15   ` Eric W. Biederman
2022-04-22 21:13     ` Sebastian Andrzej Siewior

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=20220518225355.784371-16-ebiederm@xmission.com \
    --to=ebiederm@xmission.com \
    --cc=anton.ivanov@cambridgegreys.com \
    --cc=benh@kernel.crashing.org \
    --cc=bigeasy@linutronix.de \
    --cc=chris@zankel.net \
    --cc=daniel.thompson@linaro.org \
    --cc=dianders@chromium.org \
    --cc=dietmar.eggemann@arm.com \
    --cc=dougmill@linux.vnet.ibm.com \
    --cc=ink@jurassic.park.msu.ru \
    --cc=jannh@google.com \
    --cc=jason.wessel@windriver.com \
    --cc=jcmvbkbc@gmail.com \
    --cc=johannes@sipsolutions.net \
    --cc=keescook@chromium.org \
    --cc=khuey@pernos.co \
    --cc=linux-ia64@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-um@lists.infradead.org \
    --cc=linux-xtensa@linux-xtensa.org \
    --cc=mattst88@gmail.com \
    --cc=mgorman@suse.de \
    --cc=mingo@kernel.org \
    --cc=mpe@ellerman.id.au \
    --cc=oleg@redhat.com \
    --cc=paulus@samba.org \
    --cc=peterz@infradead.org \
    --cc=richard@nod.at \
    --cc=rjw@rjwysocki.net \
    --cc=roc@pernos.co \
    --cc=rostedt@goodmis.org \
    --cc=rth@twiddle.net \
    --cc=tj@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=will@kernel.org \
    /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.