Re: [PATCH] scsi: hpsa: fix divide-by-zero in hpsa_scsi_ioaccel_raid_map

From: Don.Brace

Date: Fri Aug 14 2026 - 17:03:44 EST



________________________________________
From: Haotian Zhang <vulab@xxxxxxxxxxx>
Sent: Friday, August 14, 2026 4:00 AM
To: Don Brace - C33706 <Don.Brace@xxxxxxxxxxxxx>; James.Bottomley@xxxxxxxxxxxxxxxxxxxxx <James.Bottomley@xxxxxxxxxxxxxxxxxxxxx>; martin.petersen@xxxxxxxxxx <martin.petersen@xxxxxxxxxx>
Cc: storagedev <storagedev@xxxxxxxxxxxxx>; linux-scsi@xxxxxxxxxxxxxxx <linux-scsi@xxxxxxxxxxxxxxx>; linux-kernel@xxxxxxxxxxxxxxx <linux-kernel@xxxxxxxxxxxxxxx>; Haotian Zhang <vulab@xxxxxxxxxxx>
Subject: [PATCH] scsi: hpsa: fix divide-by-zero in hpsa_scsi_ioaccel_raid_map
 
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe

hpsa_scsi_ioaccel_raid_map() divides by blocks_per_row, the product of
data_disks_per_row and strip_size, two controller-supplied RAID map
fields that are never validated.  If either field is zero, the
unguarded division raises a divide-by-zero exception on every I/O to an
offload-enabled logical volume.

Check blocks_per_row for zero as soon as it is computed.  If it is
zero, turn off ioaccel for the device and return IO_ACCEL_INELIGIBLE.

Fixes: 283b4a9b98b1 ("[SCSI] hpsa: add ioaccell mode 1 RAID offload support.")
Signed-off-by: Haotian Zhang <vulab@xxxxxxxxxxx>


The division is already shielded by the check a few lines above it:

if (last_block >= le64_to_cpu(map->volume_blk_cnt) ||
last_block < first_block)
return IO_ACCEL_INELIGIBLE;

block_cnt is always >= 1, so last_block >= first_block >= 0.
On a self-consistent RAID map, data_disks_per_row == 0 or strip_size == 0
implies volume_blk_cnt == 0, and every I/O returns IO_ACCEL_INELIGIBLE
there without reaching the division.

Faulting requires an internally contradictory map: volume_blk_cnt > 0 with
a zero strip size or zerodata disks per row. No controller firmware produces
that, and we have not seen it in the ~17 years this code has been in the field.

Do you have any known bugs filed regarding your patch?
If not Please reword to say the condition is found by inspection
and has not been observed in practice.

---
 drivers/scsi/hpsa.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 3654b12c5d5a..fd1e07079a9c 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5206,6 +5206,10 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
        /* calculate stripe information for the request */
        blocks_per_row = le16_to_cpu(map->data_disks_per_row) *
                                le16_to_cpu(map->strip_size);
+       if (blocks_per_row == 0) {
+               hpsa_turn_off_ioaccel_for_device(dev);
+               return IO_ACCEL_INELIGIBLE;
+       }
        strip_size = le16_to_cpu(map->strip_size);
 #if BITS_PER_LONG == 32
        tmpdiv = first_block;
--
2.43.0