diff options
| author | Chandrakanth Patil <chandrakanth.patil@broadcom.com> | 2026-08-26 02:34:02 +0530 |
|---|---|---|
| committer | Martin K. Petersen (Oracle) <mkp@kernel.org> | 2026-09-09 22:08:15 -0400 |
| commit | 5dade59551d344d0308256edfef6bc3fb4202eb3 (patch) | |
| tree | 82d47dba780bd8c9ee4e59e0a4349057303d5a19 | |
| parent | 7fea128f6b829ad834f21834d2605d28a45b903d (diff) | |
| download | linux-next-5dade59551d344d0308256edfef6bc3fb4202eb3.tar.gz linux-next-5dade59551d344d0308256edfef6bc3fb4202eb3.zip | |
scsi: mpi3mr: Fix out-of-bounds bitmap access during device removal
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 <chandrakanth.patil@broadcom.com>
Link: https://patch.msgid.link/20260825210411.301535-9-chandrakanth.patil@broadcom.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
| -rw-r--r-- | drivers/scsi/mpi3mr/mpi3mr_os.c | 17 |
1 files changed, 16 insertions, 1 deletions
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)) |
