DragonFlyBSD Kernel Audit
DF-0105 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -359,9 +359,13 @@
 			queue->tq_callouts++;
 			timeout_task->f |= DT_CALLOUT_ARMED;
 		}
-		TQ_UNLOCK(queue);
+		/*
+		 * Hold TQ_LOCK across callout_reset so taskqueue_cancel_timeout's
+		 * clear of DT_CALLOUT_ARMED cannot race with our set.
+		 */
 		callout_reset(&timeout_task->c, ticks, taskqueue_timeout_func,
 			      timeout_task);
+		TQ_UNLOCK(queue);
 	}
 	return (res);
 }