[PATCH 2/3] scsi: mpi3mr: fix bitmap memory size calculation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



To allocate memory for bitmaps, the mpi3mr driver calculates sizes of
each bitmap using byte as unit. However, bit operation helper functions
assume that bitmaps are allocated using unsigned long as unit. This gap
causes memory access beyond the bitmap memory size and results in "BUG:
KASAN: slab-out-of-bounds". The BUG was observed at firmware download to
eHBA-9600. Call trace indicated that the out-of-bounds access happened
in find_first_zero_bit called from mpi3mr_send_event_ack for the bitmap
miroc->evtack_cmds_bitmap.

To avoid the BUG, fix bitmap size calculations using unsigned long as
unit. Apply this fix to five places to cover all bitmap size
calculations in the driver.

Fixes: c5758fc72b92 ("scsi: mpi3mr: Gracefully handle online FW update operation")
Fixes: e844adb1fbdc ("scsi: mpi3mr: Implement SCSI error handler hooks")
Fixes: c1af985d27da ("scsi: mpi3mr: Add Event acknowledgment logic")
Fixes: 824a156633df ("scsi: mpi3mr: Base driver code")
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx>
---
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 0c4aabaefdcc..272c318387b7 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -1160,9 +1160,8 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
 		    "\tcontroller while sas transport support is enabled at the\n"
 		    "\tdriver, please reboot the system or reload the driver\n");
 
-	dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
-	if (mrioc->facts.max_devhandle % 8)
-		dev_handle_bitmap_sz++;
+	dev_handle_bitmap_sz = sizeof(unsigned long) *
+		DIV_ROUND_UP(mrioc->facts.max_devhandle, BITS_PER_LONG);
 	if (dev_handle_bitmap_sz > mrioc->dev_handle_bitmap_sz) {
 		removepend_bitmap = krealloc(mrioc->removepend_bitmap,
 		    dev_handle_bitmap_sz, GFP_KERNEL);
@@ -2957,25 +2956,22 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
 	if (!mrioc->pel_abort_cmd.reply)
 		goto out_failed;
 
-	mrioc->dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
-	if (mrioc->facts.max_devhandle % 8)
-		mrioc->dev_handle_bitmap_sz++;
+	mrioc->dev_handle_bitmap_sz = sizeof(unsigned long) *
+		DIV_ROUND_UP(mrioc->facts.max_devhandle, BITS_PER_LONG);
 	mrioc->removepend_bitmap = kzalloc(mrioc->dev_handle_bitmap_sz,
 	    GFP_KERNEL);
 	if (!mrioc->removepend_bitmap)
 		goto out_failed;
 
-	mrioc->devrem_bitmap_sz = MPI3MR_NUM_DEVRMCMD / 8;
-	if (MPI3MR_NUM_DEVRMCMD % 8)
-		mrioc->devrem_bitmap_sz++;
+	mrioc->devrem_bitmap_sz = sizeof(unsigned long) *
+		DIV_ROUND_UP(MPI3MR_NUM_DEVRMCMD, BITS_PER_LONG);
 	mrioc->devrem_bitmap = kzalloc(mrioc->devrem_bitmap_sz,
 	    GFP_KERNEL);
 	if (!mrioc->devrem_bitmap)
 		goto out_failed;
 
-	mrioc->evtack_cmds_bitmap_sz = MPI3MR_NUM_EVTACKCMD / 8;
-	if (MPI3MR_NUM_EVTACKCMD % 8)
-		mrioc->evtack_cmds_bitmap_sz++;
+	mrioc->evtack_cmds_bitmap_sz = sizeof(unsigned long) *
+		DIV_ROUND_UP(MPI3MR_NUM_EVTACKCMD, BITS_PER_LONG);
 	mrioc->evtack_cmds_bitmap = kzalloc(mrioc->evtack_cmds_bitmap_sz,
 	    GFP_KERNEL);
 	if (!mrioc->evtack_cmds_bitmap)
@@ -3415,9 +3411,8 @@ static int mpi3mr_alloc_chain_bufs(struct mpi3mr_ioc *mrioc)
 		if (!mrioc->chain_sgl_list[i].addr)
 			goto out_failed;
 	}
-	mrioc->chain_bitmap_sz = num_chains / 8;
-	if (num_chains % 8)
-		mrioc->chain_bitmap_sz++;
+	mrioc->chain_bitmap_sz = sizeof(unsigned long) *
+		DIV_ROUND_UP(num_chains, BITS_PER_LONG);
 	mrioc->chain_bitmap = kzalloc(mrioc->chain_bitmap_sz, GFP_KERNEL);
 	if (!mrioc->chain_bitmap)
 		goto out_failed;
-- 
2.37.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux