[PATCH v3 4/5] scsi: aic94xx: bound the transaction context index from the sequencer
From: Yehyeong Lee
Date: Thu Oct 15 2026 - 05:20:53 EST
Every aSCB the driver allocates takes a slot in one shared index array,
and the driver tells the sequencer which slot it used:
/* asd_ascb_alloc() */
ascb->tc_index = asd_tc_index_get(seq, ascb);
...
ascb->scb->header.index = cpu_to_le16((u16)ascb->tc_index);
The sequencer hands that number back in the done list, and the driver
looks the aSCB up again with it in three places: asd_dl_tasklet_handler()
uses dl->index, and asd_get_response_tasklet() and
asd_get_tmf_resp_tasklet() use the index_escb field of the status block.
All three go through
static inline void *asd_tc_index_find(struct asd_seq_data *seq, int index)
{
return seq->tc_index_array[index];
}
which does not look at index at all.
The array is kcalloc()ed with tc_index_bitmap_bits entries, which is
hw_prof.max_scbs, which is asd_get_cmdctx_size() divided by sizeof(struct
scb). The two values asd_get_cmdctx_size() can return are 32768 and
65536, and struct scb starts with an 11-byte scb_header, so max_scbs
cannot exceed 5957. Both numbers the sequencer supplies are __le16, so
either one can name a slot past the end of the array, and the pointer
read from there is then dereferenced.
Check the index where it is used. The three callers already handle a NULL
return -- "Uh-oh! No escb for this dl?!" in the two status block paths
and "BUG:sequencer:dl:no ascb?!" in the done list handler -- so none of
them needs to change.
This is not a claim of a reachable out-of-bounds access: the index
originates with the driver and comes back echoed, and whether the
sequencer can echo something else is not something the tree answers,
since it is firmware loaded with request_firmware() and there is no
Documentation/ file or MAINTAINERS entry for this driver. It is a bound
on a number that arrives from outside, in the one place all three users
share.
Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx>
---
drivers/scsi/aic94xx/aic94xx_hwi.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h
index 930e192b1cd41..841769a8130a9 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.h
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.h
@@ -306,6 +306,8 @@ static inline int asd_tc_index_get(struct asd_seq_data *seq, void *ptr)
*/
static inline void *asd_tc_index_find(struct asd_seq_data *seq, int index)
{
+ if (index < 0 || index >= seq->tc_index_bitmap_bits)
+ return NULL;
return seq->tc_index_array[index];
}
--
2.43.0