⬢ DragonFlyBSD Kernel Audit
DF-4400 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/tws/tws_cam.c
+++ b/sys/dev/raid/tws/tws_cam.c
@@ -1158,11 +1158,23 @@ tws_intr_resp(struct tws_softc *sc)
     while ( tws_get_response(sc, &req_id, &mfa) ) {
         sc->stats.reqs_out++;
         if ( req_id == TWS_INVALID_REQID ) {
             TWS_TRACE_DEBUG(sc, "invalid req_id", mfa, req_id);
             sc->stats.reqs_errored++;
             tws_err_complete(sc, mfa);
             continue;
         }
+        /*
+         * The response queue is firmware-fed: validate both the index
+         * (req_id is a raw 16-bit field) and that the request is actually
+         * in flight with a completer before dereferencing cb.
+         */
+        if (req_id >= (u_int16_t)tws_queue_depth ||
+            sc->reqs[req_id].cb == NULL ||
+            sc->reqs[req_id].state == TWS_REQ_STATE_FREE) {
+            TWS_TRACE(sc, "bogus response req_id", mfa, req_id);
+            sc->stats.reqs_errored++;
+            continue;
+        }
 
         sc->reqs[req_id].cb(&sc->reqs[req_id]);
     }
 
 }