DragonFlyBSD Kernel Audit
DF-2786 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/kern_mutex.c
+++ b/sys/kern/kern_mutex.c
@@ -911,8 +911,16 @@
 	 */
 	nlock = MTX_LINKSPIN;	/* to clear */
 
+	/*
+	 * DF-2786: terminate the LINKED state BEFORE unlinking and
+	 * dropping LINKSPIN.  Previously the stale MTX_LINK_LINKED_EX/SH
+	 * state survived until mtx_wait_link() reset it to MTX_LINK_IDLE
+	 * outside LINKSPIN, letting a racing mtx_abort_link() execute the
+	 * de-link writes through the victim's dangling next/prev.
+	 */
 	switch(link->state) {
 	case MTX_LINK_LINKED_EX:
+		link->state = MTX_LINK_IDLE;
 		if (link->next == link) {
 			mtx->mtx_exlink = NULL;
 			nlock |= MTX_EXWANTED;	/* to clear */
@@ -923,6 +931,7 @@
 		}
 		break;
 	case MTX_LINK_LINKED_SH:
+		link->state = MTX_LINK_IDLE;
 		if (link->next == link) {
 			mtx->mtx_shlink = NULL;
 			nlock |= MTX_SHWANTED;	/* to clear */