git: 75be70064483 - main - umtx: Do not make an exiting thread the owner of a PI mutex

Mark Johnston <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src,gmane.os.freebsd.current.scm
Message-ID <[email protected]>
The branch main has been updated by markj:

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

commit 75be70064483158da2b89ab412f83a4694560e58
Author:     Mark Johnston <[email protected]>
AuthorDate: 2026-07-27 23:12:37 +0000
Commit:     Mark Johnston <[email protected]>
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);
 		}
 	}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.