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

Haotian Zhang <[email protected]>
Newsgroups gmane.linux.scsi,gmane.linux.kernel
Message-ID <[email protected]>
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]>
---
 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.