Linux SCSI subsystem development
 help / color / mirror / Atom feed
* [PATCH] scsi: mpi3mr: Fix integer overflow in reply frame size calculation
@ 2026-11-03 12:33 Milan P. Gandhi
  2026-11-03 12:49 ` sashiko-bot
  2026-11-05 12:24 ` [PATCH v2] scsi: mpi3mr: Validate reply frame size bounds Milan P. Gandhi
  0 siblings, 2 replies; 7+ messages in thread
From: Milan P. Gandhi @ 2026-11-03 12:33 UTC (permalink / raw)
  To: sathya.prakash, kashyap.desai, sumit.saxena, sreekanth.reddy,
	martin.petersen
  Cc: linux-scsi, mgandhi, stable

The driver reads reply_frame_size from firmware as a u16 value in dwords
and multiplies by 4 to convert to bytes. If the firmware (malicious or
buggy) provides a value greater than U16_MAX / 4, the multiplication
overflows the u16 result before assignment to mrioc->facts.reply_sz.

For example:
  reply_frame_size = 20000 dwords
  20000 * 4 = 80000 bytes (as int)
  Assigned to u16: 80000 & 0xFFFF = 14464 bytes (truncated)

This truncated value is then used to allocate DMA reply buffers via
kzalloc(). The firmware believes it can send 80000-byte replies, but
the driver only allocated 14464 bytes, causing a heap buffer overflow
when the firmware DMAs the full-sized reply.

Additionally, if firmware reports reply_frame_size == 0, facts.reply_sz
becomes 0, which can cause division-by-zero or zero-sized DMA pool
allocations downstream.

Fix by validating reply_frame_size in mpi3mr_issue_iocfacts() before
processing the facts data. Reject values that are zero or would overflow
u16 when converted to bytes.

An attacker with firmware control could exploit this to corrupt kernel
heap memory via DMA, potentially leading to privilege escalation.

Fixes: 824a156633df ("scsi: mpi3mr: Base driver code")
Cc: stable@vger.kernel.org
Signed-off-by: Milan P. Gandhi <mgandhi@redhat.com>
---
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index f0d3cd398dd0..2b72218e79fb 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -3261,6 +3261,7 @@ static int mpi3mr_issue_iocfacts(struct mpi3mr_ioc *mrioc,
 	struct mpi3_ioc_facts_data *facts_data)
 {
 	struct mpi3_ioc_facts_request iocfacts_req;
+	u16 reply_frame_size;
 	void *data = NULL;
 	dma_addr_t data_dma;
 	u32 data_len = sizeof(*facts_data);
@@ -3318,6 +3319,19 @@ static int mpi3mr_issue_iocfacts(struct mpi3mr_ioc *mrioc,
 		goto out_unlock;
 	}
 	memcpy(facts_data, (u8 *)data, data_len);
+
+	reply_frame_size = le16_to_cpu(facts_data->reply_frame_size);
+	/*
+	 * Validate reply_frame_size to prevent integer overflow when
+	 * converting dwords to bytes (reply_frame_size * 4).
+	 */
+	if (!reply_frame_size || reply_frame_size > (U16_MAX / 4)) {
+		ioc_err(mrioc, "Invalid reply_frame_size %u from firmware\n",
+			reply_frame_size);
+		retval = -EINVAL;
+		goto out_unlock;
+	}
+
 	mpi3mr_process_factsdata(mrioc, facts_data);
 out_unlock:
 	mrioc->init_cmds.state = MPI3MR_CMD_NOTUSED;
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-11-09  3:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 12:33 [PATCH] scsi: mpi3mr: Fix integer overflow in reply frame size calculation Milan P. Gandhi
2026-11-03 12:49 ` sashiko-bot
2026-11-03 13:11   ` Milan P. Gandhi
2026-11-05 12:24 ` [PATCH v2] scsi: mpi3mr: Validate reply frame size bounds Milan P. Gandhi
2026-11-05 12:45   ` sashiko-bot
2026-11-05 13:37     ` Milan P. Gandhi
2026-11-09  3:55   ` Martin K. Petersen (Oracle)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox