[PATCH v5 3/6] scsi: mvumi: bound the hotplug event bitmap
From: Yehyeong Lee
Date: Wed Oct 14 2026 - 11:21:19 EST
mvumi_proc_msg() takes size from the hotplug event the firmware DMAs into
the event buffer and uses it twice: as the bit count for two
find_next_zero_bit() scans, and as the byte offset of the second bitmap.
Nothing checks it against the buffer, which mvumi_get_event() allocates at
a fixed 512 bytes, and size is a u16, so a firmware reporting 65535 makes
both scans run roughly 8 KiB past the allocation and places the second
bitmap past it to begin with.
Reject a size whose bitmaps do not fit the buffer. The second bitmap
starts size bits in and find_next_zero_bit() reads a long at a time, so
that span is the furthest either scan reaches; compare it against the
buffer and give the buffer size a name so the bound and the allocation
cannot drift apart. Read size once, since it lives in memory the
firmware can still write.
Fixes: bd756ddea18e ("[SCSI] mvumi: Add support for Marvell SAS/SATA RAID-on-Chip(ROC) 88RC9580")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Yehyeong Lee <yhlee@xxxxxxxxxxxxxxxxxx>
---
drivers/scsi/mvumi.c | 16 ++++++++++++++--
drivers/scsi/mvumi.h | 3 +++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c
index 2378b676a7a78..9e342db4b8383 100644
--- a/drivers/scsi/mvumi.c
+++ b/drivers/scsi/mvumi.c
@@ -1652,11 +1652,23 @@ static int mvumi_rescan_bus(void *data)
static void mvumi_proc_msg(struct mvumi_hba *mhba,
struct mvumi_hotplug_event *param)
{
- u16 size = param->size;
+ u16 size = READ_ONCE(param->size);
const unsigned long *ar_bitmap;
const unsigned long *re_bitmap;
int index;
+ /*
+ * The second bitmap starts size bits into the event buffer and
+ * find_next_zero_bit() reads it a long at a time, so that is the
+ * furthest the two scans reach.
+ */
+ if (sizeof(*param) + (size >> 3) + BITS_TO_LONGS(size) * sizeof(long) >
+ MVUMI_EVENT_BUF_SIZE) {
+ dev_err(&mhba->pdev->dev,
+ "invalid hotplug event bitmap size %u\n", size);
+ return;
+ }
+
if (mhba->fw_flag & MVUMI_FW_ATTACH) {
index = -1;
ar_bitmap = (const unsigned long *) param->bitmap;
@@ -1708,7 +1720,7 @@ static int mvumi_get_event(struct mvumi_hba *mhba, unsigned char msg)
struct mvumi_cmd *cmd;
struct mvumi_msg_frame *frame;
- cmd = mvumi_create_internal_cmd(mhba, 512);
+ cmd = mvumi_create_internal_cmd(mhba, MVUMI_EVENT_BUF_SIZE);
if (!cmd)
return -1;
cmd->scmd = NULL;
diff --git a/drivers/scsi/mvumi.h b/drivers/scsi/mvumi.h
index 1306a4abf19ad..5d45f0d99e639 100644
--- a/drivers/scsi/mvumi.h
+++ b/drivers/scsi/mvumi.h
@@ -124,6 +124,9 @@ enum {
#define APICDB1_HOST_GETEVENT 1
#define MAX_EVENTS_RETURNED 6
+/* size of the buffer the driver hands the firmware for event replies */
+#define MVUMI_EVENT_BUF_SIZE 512
+
#define DEVICE_OFFLINE 0
#define DEVICE_ONLINE 1
--
2.43.0