DF-4274 / fix.diff
--- 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); } } |