Re: [PATCH] scsi: hpsa: fix divide-by-zero in hpsa_scsi_ioaccel_raid_map
| Newsgroups | gmane.linux.scsi,gmane.linux.kernel |
|---|---|
| Message-ID | <SJ2PR11MB836968B883E0A657E695FB7CE1DA2@SJ2PR11MB8369.namprd11.prod.outlook.com> |
________________________________________ From: Haotian Zhang <[email protected]> Sent: Friday, August 14, 2026 4:00 AM To: Don Brace - C33706 <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]> Cc: storagedev <[email protected]>; [email protected] <[email protected]>; [email protected] <[email protected]>; Haotian Zhang <[email protected]> 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 <[email protected]> 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