git: 7688c099fc21 - MFC r368735: Fix a race in tty_signal_sessleader() with unlocked read of s_leader.

Konstantin Belousov kib at FreeBSD.org
Thu Dec 24 11:13:14 UTC 2020


The branch stable/12 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=7688c099fc21d20fe0cf1bc3097b4a0ce5178753

commit 7688c099fc21d20fe0cf1bc3097b4a0ce5178753
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2020-12-17 19:51:39 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2020-12-24 10:56:35 +0000

    MFC r368735:
    Fix a race in tty_signal_sessleader() with unlocked read of s_leader.
    
    (cherry picked from commit 551e205f6dfa469f4f32a166ee3fb691201d27a7)
---
 sys/kern/tty.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 3cd0262d6042..f82c1feca021 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -1462,6 +1462,7 @@ void
 tty_signal_sessleader(struct tty *tp, int sig)
 {
 	struct proc *p;
+	struct session *s;
 
 	tty_assert_locked(tp);
 	MPASS(sig >= 1 && sig < NSIG);
@@ -1469,8 +1470,14 @@ tty_signal_sessleader(struct tty *tp, int sig)
 	/* Make signals start output again. */
 	tp->t_flags &= ~TF_STOPPED;
 
-	if (tp->t_session != NULL && tp->t_session->s_leader != NULL) {
-		p = tp->t_session->s_leader;
+	/*
+	 * Load s_leader exactly once to avoid race where s_leader is
+	 * set to NULL by a concurrent invocation of killjobc() by the
+	 * session leader.  Note that we are not holding t_session's
+	 * lock for the read.
+	 */
+	if ((s = tp->t_session) != NULL &&
+	    (p = atomic_load_ptr(&s->s_leader)) != NULL) {
 		PROC_LOCK(p);
 		kern_psignal(p, sig);
 		PROC_UNLOCK(p);


More information about the dev-commits-src-all mailing list