diff --git a/sys/dev/raid/tws/tws_cam.c b/sys/dev/raid/tws/tws_cam.c --- a/sys/dev/raid/tws/tws_cam.c +++ b/sys/dev/raid/tws/tws_cam.c @@ -510,6 +510,14 @@ hdr = sen->hdr; TWS_TRACE_DEBUG(sc, "sen, hdr", sen, hdr); req_id = hdr->header_desc.request_id; + /* + * DF-1590: tws_err_complete had NO req_id bound check at all + * (not even INVALID). Validate before indexing sc->reqs[]. + */ + if (req_id >= tws_queue_depth) { + TWS_TRACE_DEBUG(sc, "invalid req_id in sense", req_id, req_id); + return; + } req = &sc->reqs[req_id]; TWS_TRACE_DEBUG(sc, "req, id", req, req_id); if ( req->error_code != TWS_REQ_SUBMIT_SUCCESS ) @@ -1160,7 +1168,13 @@ while ( tws_get_response(sc, &req_id, &mfa) ) { sc->stats.reqs_out++; - if ( req_id == TWS_INVALID_REQID ) { + /* + * DF-1590: req_id is a u16 from firmware DMA reply; reqs[] is + * sized tws_queue_depth (<=256). Without an upper bound the + * cb() call below derefs an out-of-bounds struct that the + * firmware completely controls. + */ + if ( req_id == TWS_INVALID_REQID || req_id >= tws_queue_depth ) { TWS_TRACE_DEBUG(sc, "invalid req_id", mfa, req_id); sc->stats.reqs_errored++; tws_err_complete(sc, mfa);