svn commit: r368735 - head/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Thu Dec 17 19:51:39 UTC 2020
Author: kib
Date: Thu Dec 17 19:51:39 2020
New Revision: 368735
URL: https://svnweb.freebsd.org/changeset/base/368735
Log:
Fix a race in tty_signal_sessleader() with unlocked read of s_leader.
Since we do not own the session lock, a parallel killjobc() might
reset s_leader to NULL after we checked it. Read s_leader only once
and ensure that compiler is not allowed to reload.
While there, make access to t_session somewhat more pretty by using
local variable.
PR: 251915
Submitted by: Jakub Piecuch <j.piecuch96 at gmail.com>
MFC after: 1 week
Modified:
head/sys/kern/tty.c
Modified: head/sys/kern/tty.c
==============================================================================
--- head/sys/kern/tty.c Thu Dec 17 19:50:41 2020 (r368734)
+++ head/sys/kern/tty.c Thu Dec 17 19:51:39 2020 (r368735)
@@ -1474,6 +1474,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);
@@ -1482,8 +1483,14 @@ tty_signal_sessleader(struct tty *tp, int sig)
tp->t_flags &= ~TF_STOPPED;
tp->t_termios.c_lflag &= ~FLUSHO;
- 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 svn-src-head
mailing list