DragonFlyBSD Kernel Audit
DF-2661 / fix.diff
← back to finding ↓ download raw
--- a/sys/vfs/hammer2/hammer2_io.c
+++ b/sys/vfs/hammer2/hammer2_io.c
@@ -356,6 +356,19 @@
 	dio->error = error;
 
 	/*
+	 * DF-2661: If the I/O failed, dispose of the buffer now.  Leaving
+	 * dio->bp set with DIO_GOOD clear violates the DIO state machine:
+	 * any subsequent accessor that acquires DIO_INPROG expects
+	 * dio->bp == NULL (and asserts it), and on non-INVARIANTS kernels
+	 * the DOP_NEW path would overwrite the pointer without releasing
+	 * the buffer, orphaning a buffer-lock.
+	 */
+	if (error && dio->bp) {
+		brelse(dio->bp);
+		dio->bp = NULL;
+	}
+
+	/*
 	 * Clear INPROG and WAITING, set GOOD wake up anyone waiting.
 	 */
 	for (;;) {