⬢ DragonFlyBSD Kernel Audit
DF-4274 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/twa/tw_osl_freebsd.c
+++ b/sys/dev/raid/twa/tw_osl_freebsd.c
@@ -1279,8 +1279,14 @@ out:
 		 * If the caller had been returned EINPROGRESS, and he has
 		 * registered a callback for handling completion, the callback
 		 * will never get called because we were unable to submit the
 		 * request.  So, free up the request right here.
 		 */
-		if (req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS)
+		/*
+		 * Only for asynchronous owners (CAM I/O whose originator has
+		 * already returned).  A PASSTHRU request's originator is
+		 * still blocked in tw_osli_fw_passthru() and returns the
+		 * request to the free queue itself at its fw_passthru_err
+		 * label; inserting it here too puts the same link on the
+		 * free queue twice (queue corruption / request reuse UAF).
+		 */
+		if ((req->flags & TW_OSLI_REQ_FLAGS_IN_PROGRESS) &&
+		    !(req->flags & TW_OSLI_REQ_FLAGS_PASSTHRU))
 			tw_osli_req_q_insert_tail(req, TW_OSLI_FREE_Q);
 	}
 }