[PATCH v2 08/17] mpi3mr: Fix out-of-bounds bitmap access during device removal
Chandrakanth Patil <[email protected]>
| Newsgroups | org.kernel.vger.linux-scsi |
|---|---|
| Message-ID | <[email protected]> |
Device handles reported by the controller are used to index the remove
pending bitmap and to build a task management request without being
compared against the maximum handle the controller reported.
Check the handle before using it.
Fixes: 13ef29ea4aa0 ("scsi: mpi3mr: Add support for device add/remove event handling")
Signed-off-by: Chandrakanth Patil <[email protected]>
---
v2:
- Relocated handle bounds check to the entry of mpi3mr_dev_rmhs_send_tm()
so out-of-bounds handles are rejected immediately without polluting
delayed_rmhs_list.
drivers/scsi/mpi3mr/mpi3mr_os.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index f80a21ec161b..2a35f146fe69 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -2401,7 +2401,8 @@ static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_ioc *mrioc,
ioc_info(mrioc,
"%s :dev removal handshake completed successfully: handle(0x%04x)\n",
__func__, drv_cmd->dev_handle);
- clear_bit(drv_cmd->dev_handle, mrioc->removepend_bitmap);
+ if (drv_cmd->dev_handle < mrioc->facts.max_devhandle)
+ clear_bit(drv_cmd->dev_handle, mrioc->removepend_bitmap);
}
if (!list_empty(&mrioc->delayed_rmhs_list)) {
@@ -2515,6 +2516,20 @@ static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_ioc *mrioc, u16 handle,
struct mpi3mr_tgt_dev *tgtdev = NULL;
unsigned long flags;
+ if (handle >= mrioc->facts.max_devhandle) {
+ ioc_err(mrioc, "dev_remove_hs: handle(0x%04x) >= max_devhandle(0x%04x)\n",
+ handle, mrioc->facts.max_devhandle);
+ if (drv_cmd) {
+ cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN;
+ drv_cmd->state = MPI3MR_CMD_NOTUSED;
+ drv_cmd->callback = NULL;
+ drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE;
+ drv_cmd->retry_count = 0;
+ clear_bit(cmd_idx, mrioc->devrem_bitmap);
+ }
+ return;
+ }
+
spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
tgtdev = __mpi3mr_get_tgtdev_by_handle(mrioc, handle);
if (tgtdev && (iou_rc == MPI3_CTRL_OP_REMOVE_DEVICE))
--
2.52.0