Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Chandrakanth Patil" <chandrakanth.patil@broadcom.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH 14/17] mpi3mr: Fix out-of-bounds read in PCIe topology change events
Date: Tue, 18 Aug 2026 18:23:09 +0000	[thread overview]
Message-ID: <20260818182309.9BCE91F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260818231426.58105-15-chandrakanth.patil@broadcom.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [High] The newly added bounds check reads `topo_evt->num_entries` directly from a DMA-mapped buffer, and the subsequent loop condition re-reads it, creating a Time-Of-Check to Time-Of-Use (TOCTOU) race condition.

Pre-existing issues:
- [High] The bounds check for PCIe and SAS topology change events fails to protect the bottom-half event handlers from out-of-bounds reads because early returns in the top-half do not prevent the malformed event from being queued.
- [High] The bounds check uses an untrusted `event_data_length` without verifying it against the actual physical dimensions of the hardware reply buffer, allowing an out-of-bounds read in the top-half handler.
- [High] Missing `dma_rmb()` after polling the phase bit in DMA-mapped reply descriptors, which can lead to processing stale descriptor data on weakly ordered architectures.
--

--- Patch [14]: [PATCH 14/17] mpi3mr: Fix out-of-bounds read in PCIe topology change events ---
commit 8553af34c1ff3c0cff0462ca66842979af8cb4d4
Author: Chandrakanth Patil <chandrakanth.patil@broadcom.com>

mpi3mr: Fix out-of-bounds read in PCIe topology change events
    
The number of entries in a PCIe topology change event is used to walk
the entry array without being compared against the amount of event
data that was received. Bound the entry count to the received event data
before use.

> diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> @@ -2753,11 +2753,26 @@ static void mpi3mr_pcietopochg_evt_th(struct mpi3mr_ioc *mrioc,
>  	struct mpi3_event_data_pcie_topology_change_list *topo_evt =
>  	    (struct mpi3_event_data_pcie_topology_change_list *)event_reply->event_data;
>  	int i;
> -	u16 handle;
> -	u8 reason_code;
> +	u16 handle, avail_len;
> +	u8 reason_code, max_entries;
>  	struct mpi3mr_tgt_dev *tgtdev = NULL;
>  	struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL;
>  
> +	avail_len = event_reply->event_data_length * 4;

[Severity: High]
This isn't a bug introduced by this patch, but could this calculation
exceed the actual physical dimensions of the hardware reply buffer?

Because avail_len is derived strictly from the untrusted event_data_length,
a compromised or malicious device could provide a value larger than the
allocated DMA reply buffer (mrioc->reply_sz).

Should we verify event_data_length against mrioc->reply_sz to prevent
the bounds check from being artificially inflated, which would lead to an
out-of-bounds read? 

The SAS topology handler mpi3mr_sastopochg_evt_th() appears to share this
exact pattern.

> +	if (avail_len < offsetof(struct mpi3_event_data_pcie_topology_change_list, port_entry)) {
> +		ioc_err(mrioc, "PCIe topology event: event data too small (%u bytes)\n",
> +			avail_len);
> +		return;
> +	}
> +	max_entries = (avail_len -
> +		      offsetof(struct mpi3_event_data_pcie_topology_change_list, port_entry)) /
> +		      sizeof(struct mpi3_event_pcie_topo_port_entry);
> +	if (topo_evt->num_entries > max_entries) {
> +		ioc_err(mrioc, "PCIe topology event: num_entries(%d) exceeds max(%d)\n",
> +			topo_evt->num_entries, max_entries);
> +		return;
> +	}

[Severity: High]
This is a pre-existing issue, but does this early return actually prevent
the malformed event from being processed by the bottom-half handler?

When mpi3mr_pcietopochg_evt_th() returns early here, the process_evt_bh flag
remains set in mpi3mr_os_handle_events():

drivers/scsi/mpi3mr/mpi3mr_os.c:mpi3mr_os_handle_events() {
    ...
	case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
	{
		process_evt_bh = 1;
		mpi3mr_pcietopochg_evt_th(mrioc, event_reply);
		break;
	}
    ...
}

Since process_evt_bh remains 1, the event is queued to the worker thread.
The bottom-half handler mpi3mr_pcietopochg_evt_bh() will then blindly
iterate up to the unvalidated event_data->num_entries, causing an
out-of-bounds read past the end of the allocated fwevt heap buffer.

Would it be safer to clear process_evt_bh or return a status from the
top-half handler to prevent queuing malformed events? The SAS topology
handler mpi3mr_sastopochg_evt_bh() is likely vulnerable to the exact
same incomplete fix flaw.

>  
>  	for (i = 0; i < topo_evt->num_entries; i++) {
>  		handle = le16_to_cpu(topo_evt->port_entry[i].attached_dev_handle);
>  		if (!handle)

[Severity: High]
Is this loop vulnerable to a Time-Of-Check to Time-Of-Use (TOCTOU) race
condition?

The newly added bounds check reads topo_evt->num_entries directly from a
DMA-mapped buffer, and this loop condition continually re-evaluates it. 

Because the loop body contains functions that acquire spinlocks
(e.g., mpi3mr_get_tgtdev_by_handle()), which act as full compiler memory
barriers, the compiler is forced to re-fetch num_entries from DMA memory
on every iteration.

If a malicious device alters num_entries in DMA memory after the initial
max_entries check, could it extend the loop beyond bounds? 

Should we cache num_entries in a local variable before the bounds check
and use the local variable for the loop condition? The SAS topology handler
mpi3mr_sastopochg_evt_th() appears to have the identical issue.

[Severity: High]
This isn't a bug introduced by this patch, but is a dma_rmb() barrier needed
after polling the phase bit in the DMA-mapped reply descriptors?

Looking at mpi3mr_process_op_reply_q() in drivers/scsi/mpi3mr/mpi3mr_fw.c:

drivers/scsi/mpi3mr/mpi3mr_fw.c:mpi3mr_process_op_reply_q() {
    ...
	if ((le16_to_cpu(reply_desc->reply_flags) &
	    MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) {
		atomic_dec(&op_reply_q->in_use);
		return 0;
	}

	do {
		if (mrioc->unrecoverable || mrioc->io_admin_reset_sync)
			break;

		req_q_idx = le16_to_cpu(reply_desc->request_queue_id) - 1;
    ...
}

The driver polls the hardware DMA ring by checking the reply_flags phase mask.
Without a subsequent dma_rmb(), weakly ordered CPU architectures (such as
ARM64) can speculatively execute out-of-order reads and fetch the rest of
the descriptor payload (like request_queue_id) before the hardware has
actually committed the updated descriptor.

Could this result in processing corrupted or stale descriptor payloads?
There appears to be a similar polling loop for the admin reply queue in
mpi3mr_process_admin_reply_q() lacking a dma_rmb() before accessing
request_queue_ci.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260818231426.58105-1-chandrakanth.patil@broadcom.com?part=14

  reply	other threads:[~2026-08-18 18:23 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-18 23:14 [PATCH 0/17] mpi3mr: fix out-of-bounds accesses and reference leaks Chandrakanth Patil
2026-08-18 23:14 ` [PATCH 01/17] mpi3mr: Fix buffer overflow in BSG passthrough request copy Chandrakanth Patil
2026-08-18 18:14   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 02/17] mpi3mr: Fix out-of-bounds read when copying BSG MPI requests Chandrakanth Patil
2026-08-18 18:15   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 03/17] mpi3mr: Fix I/O block counter leak on admin request post failure Chandrakanth Patil
2026-08-18 18:11   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 04/17] mpi3mr: Fix target device reference leak in BSG task management Chandrakanth Patil
2026-08-18 18:13   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 05/17] mpi3mr: Fix buffer overflow when caching log data Chandrakanth Patil
2026-08-18 23:14 ` [PATCH 06/17] mpi3mr: Fix out-of-bounds reply frame access Chandrakanth Patil
2026-08-18 18:11   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 07/17] mpi3mr: Fix out-of-bounds sense buffer access Chandrakanth Patil
2026-08-18 18:11   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 08/17] mpi3mr: Fix out-of-bounds bitmap access during device removal Chandrakanth Patil
2026-08-18 18:13   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 09/17] mpi3mr: Fix target device reference leak in device removal handshake Chandrakanth Patil
2026-08-18 18:18   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 10/17] mpi3mr: Fix out-of-bounds read in SAS topology change events Chandrakanth Patil
2026-08-18 18:10   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 11/17] mpi3mr: Fix out-of-bounds read of event data Chandrakanth Patil
2026-08-18 18:16   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 12/17] mpi3mr: Fix out-of-bounds phy array access on link change Chandrakanth Patil
2026-08-18 18:33   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 13/17] mpi3mr: Fix buffer overflow in the BSG target device map Chandrakanth Patil
2026-08-18 23:14 ` [PATCH 14/17] mpi3mr: Fix out-of-bounds read in PCIe topology change events Chandrakanth Patil
2026-08-18 18:23   ` sashiko-bot [this message]
2026-08-18 23:14 ` [PATCH 15/17] mpi3mr: zero out diagnostic buffer status memory Chandrakanth Patil
2026-08-18 18:21   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 16/17] mpi3mr: Fix use-after-free of the firmware event workqueue Chandrakanth Patil
2026-08-18 18:23   ` sashiko-bot
2026-08-18 23:14 ` [PATCH 17/17] mpi3mr: Fix NULL pointer dereference on PCI error recovery Chandrakanth Patil
2026-08-18 18:32   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260818182309.9BCE91F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=chandrakanth.patil@broadcom.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox