⬢ DragonFlyBSD Kernel Audit
DF-3515 / fix.diff
← back to finding ↓ download raw
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -885,10 +885,21 @@
 	 * If the operation is still in-progress then re-acquire the spin-lock
 	 * and block if necessary.  Also initiate the lock cancel.
 	 */
-	if (sync == 0 || (c->flags & (CALLOUT_INPROG | CALLOUT_SET)) == 0) {
+	if (sync == 0) {
 		exis_drop_gd(gd);
 		return 0;
 	}
+	if ((c->flags & (CALLOUT_INPROG | CALLOUT_SET)) == 0) {
+		/*
+		 * The request may have been completed inline by
+		 * _callout_update_spinlocked() (e.g. a wheel-pending
+		 * callout removed by our STOP/CANCEL request): SET is
+		 * already clear and CALLOUT_PREVENTED records whether
+		 * we were responsible.  Report that instead of 0.
+		 */
+		exis_drop_gd(gd);
+		return ((c->flags & CALLOUT_PREVENTED) != 0);
+	}
 	if (c->flags & CALLOUT_AUTOLOCK)
 		lockmgr(c->lk, LK_CANCEL_BEG);
 	spin_lock(&c->spin);