Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Jul 2026 23:14:56 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 75be70064483 - main - umtx: Do not make an exiting thread the owner of a PI mutex
Message-ID:  <6a67e670.306ef.5fc3393b@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=75be70064483158da2b89ab412f83a4694560e58

commit 75be70064483158da2b89ab412f83a4694560e58
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-27 23:12:37 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-07-27 23:12:37 +0000

    umtx: Do not make an exiting thread the owner of a PI mutex
    
    Otherwise an assertion in umtx_thread_alloc()
    (TAILQ_EMPTY(&uq->uq_pi_contested)) is violated.
    
    This use of TDB_EXIT is hacky, but I cannot see another way to check for
    an exiting thread without adding some more overhead to kern_thr_exit().
    
    Fixes:          2a339d9e3dc1
    Reported by:    Maik Muench of Secfault Security
    Reviewed by:    kib
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58447
---
 sys/kern/kern_umtx.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index ab6e578ab380..4f6e2b339ba6 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -2028,7 +2028,7 @@ int
 umtxq_sleep_pi(struct umtx_q *uq, struct umtx_pi *pi, uint32_t owner,
     const char *wmesg, struct umtx_abs_timeout *timo, bool shared)
 {
-	struct thread *td, *td1;
+	struct thread *td;
 	struct umtx_q *uq1;
 	int error, pri;
 #ifdef INVARIANTS
@@ -2044,13 +2044,22 @@ umtxq_sleep_pi(struct umtx_q *uq, struct umtx_pi *pi, uint32_t owner,
 	umtxq_insert(uq);
 	mtx_lock(&umtx_lock);
 	if (pi->pi_owner == NULL) {
+		struct thread *ownertd;
+
 		mtx_unlock(&umtx_lock);
-		td1 = tdfind(owner, shared ? -1 : td->td_proc->p_pid);
+		ownertd = tdfind(owner, shared ? -1 : td->td_proc->p_pid);
 		mtx_lock(&umtx_lock);
-		if (td1 != NULL) {
-			if (pi->pi_owner == NULL)
-				umtx_pi_setowner(pi, td1);
-			PROC_UNLOCK(td1->td_proc);
+		if (ownertd != NULL) {
+			/*
+			 * An exiting thread that has already called
+			 * umtx_thread_exit() must not be made the owner of a
+			 * shared mutex.
+			 */
+			if ((ownertd->td_proc->p_flag & P_WEXIT) == 0 &&
+			    (ownertd->td_dbgflags & TDB_EXIT) == 0 &&
+			    pi->pi_owner == NULL)
+				umtx_pi_setowner(pi, ownertd);
+			PROC_UNLOCK(ownertd->td_proc);
 		}
 	}
 


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a67e670.306ef.5fc3393b>