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 01/17] mpi3mr: Fix buffer overflow in BSG passthrough request copy
Date: Tue, 18 Aug 2026 18:14:45 +0000	[thread overview]
Message-ID: <20260818181445.E16AC1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260818231426.58105-2-chandrakanth.patil@broadcom.com>

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

Pre-existing issues:
- [Critical] Pointer arithmetic wrap-around on 32-bit architectures allows bypassing bounds checks, leading to arbitrary kernel memory read/write via DMA.
- [High] DMA coherent memory allocated for NVMe PRPs is leaked on BSG command timeout or submission failure.
- [High] Target device `block_io` atomic counter is leaked if BSG command submission fails.
- [High] Lockless TOCTOU check of `MPI3MR_CMD_COMPLETE` causes a Use-After-Free of `sense_buff_k` and data races on `reply` buffers.
- [High] Missing validation of the BSG request length (`job->request_len`) allows a user to send an undersized request buffer, leading to out-of-bounds memory reads and kernel panics.
--

--- Patch [1]: [PATCH 01/17] mpi3mr: Fix buffer overflow in BSG passthrough request copy ---
commit ed6513158d24e842e223917348ef598d4d161609
Author: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
Subject: mpi3mr: Fix buffer overflow in BSG passthrough request copy

This commit fixes a buffer overflow in the BSG passthrough request copy.
The check for an incoming BSG request size used a narrower variable than
its source field, allowing large values to wrap and pass the check.
The variable is widened to ensure the full size is validated properly.

> diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
> index 1353a8ff9c85d..8e5d24793efd0 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_app.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
> @@ -2384,7 +2384,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
>  	long rval = -EINVAL;
>  	struct mpi3mr_ioc *mrioc = NULL;
>  	u8 *mpi_req = NULL, *sense_buff_k = NULL;
> -	u8 mpi_msg_size = 0;
> +	u32 mpi_msg_size = 0;
>  	struct mpi3mr_bsg_packet *bsg_req = NULL;
>  	struct mpi3mr_bsg_mptcmd *karg;
>  	struct mpi3mr_buf_entry *buf_entries = NULL;
> @@ -2538,7 +2538,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
>  				rval = -EINVAL;
>  				goto out;
>  			}
> -			memcpy(mpi_req, sgl_iter, buf_entries->buf_len);
> +			memcpy(mpi_req, sgl_iter, mpi_msg_size);
>  			break;
>  		default:
>  			invalid_be = 1;

[Severity: Critical]
This is a pre-existing issue, but can the pointer arithmetic nearby lead to
an integer wrap-around on 32-bit architectures?

When iterating over buffer entries in the same function:

	case MPI3MR_BSG_BUFTYPE_DATA_OUT:
		sgl_iter = sgl_dout_iter;
		sgl_dout_iter += buf_entries->buf_len;

If a user submits a BSG request with a crafted buf_len, does the u32 value wrap
the sgl_dout_iter pointer on 32-bit systems? This wrapped pointer could then
bypass the later bounds check:

	if (sgl_dout_iter > (dout_buf + job->request_payload.payload_len)) {

and allow arbitrary kernel memory access during subsequent payload processing.

While reviewing this patch, I noticed a few other pre-existing issues.

> drivers/scsi/mpi3mr/mpi3mr_app.c:mpi3mr_bsg_request()
> {
> 	long rval = -EINVAL;
> 	unsigned int reply_payload_rcv_len = 0;
> 
> 	struct mpi3mr_bsg_packet *bsg_req = job->request;
> 
> 	switch (bsg_req->cmd_type) {

[Severity: High]
This isn't a bug introduced by this patch, but does this function properly
validate job->request_len before dereferencing bsg_req->cmd_type?

If userspace submits a BSG request with a request_len of zero, could this
trigger a zero size pointer dereference and cause a kernel panic? Similarly,
if the length is too small, would this read uninitialized heap memory?

> drivers/scsi/mpi3mr/mpi3mr_app.c:mpi3mr_bsg_process_mpt_cmds()
> {
[ ... ]
> 	if (block_io) {
> 		tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, dev_handle);
> 		if (tgtdev && tgtdev->starget && tgtdev->starget->hostdata) {
> 			stgt_priv = (struct mpi3mr_stgt_priv_data *)
> 			    tgtdev->starget->hostdata;
> 			atomic_inc(&stgt_priv->block_io);
> 			mpi3mr_tgtdev_put(tgtdev);
> 		}
> 	}
[ ... ]
> 	rval = mpi3mr_admin_request_post(mrioc, mpi_req,
> 	    MPI3MR_ADMIN_REQ_FRAME_SZ, 0);
> 
> 	if (rval) {
> 		mrioc->bsg_cmds.is_waiting = 0;
> 		dprint_bsg_err(mrioc,
> 		    "%s: posting bsg request is failed\n", __func__);
> 		rval = -EAGAIN;
> 		goto out_unlock;
> 	}

[Severity: High]
This is a pre-existing issue, but does this error path permanently leak the
block_io atomic counter?

If mpi3mr_admin_request_post() fails, the goto out_unlock bypasses the
atomic_dec(&stgt_priv->block_io) that occurs after the completion timeout
logic. Does this leave the SCSI target device blocked indefinitely?

[Severity: High]
Similarly, this is a pre-existing issue, but does the same goto out_unlock
skip freeing the DMA memory allocated for NVMe PRPs?

If mpi3mr_build_nvme_prp() successfully allocated DMA memory in
mrioc->prp_list_virt earlier in this function, the jump to out_unlock skips
the success-path cleanup block:

	if (mrioc->prp_list_virt) {
		dma_free_coherent(&mrioc->pdev->dev, mrioc->prp_sz,
		    mrioc->prp_list_virt, mrioc->prp_list_dma);

Would subsequent commands overwrite mrioc->prp_list_virt and permanently
leak the previous DMA coherent allocation?

> drivers/scsi/mpi3mr/mpi3mr_fw.c:mpi3mr_process_admin_reply_desc()
> {
[ ... ]
> 	cmdptr = mpi3mr_get_drv_cmd(mrioc, host_tag, def_reply);
> 	if (cmdptr) {
> 		if (cmdptr->state & MPI3MR_CMD_PENDING) {
> 			cmdptr->state |= MPI3MR_CMD_COMPLETE;
> 			cmdptr->ioc_loginfo = ioc_loginfo;
[ ... ]
> 			if (sense_buf && cmdptr->sensebuf) {
> 				cmdptr->is_sense = 1;
> 				memcpy(cmdptr->sensebuf, sense_buf,
> 				       MPI3MR_SENSE_BUF_SZ);
> 			}

[Severity: High]
This isn't a bug introduced by this patch, but does setting the
MPI3MR_CMD_COMPLETE flag before the memory copy create a race condition?

If the application thread in mpi3mr_bsg_process_mpt_cmds() wakes up from a
natural timeout exactly when this flag is set, it performs a lockless check:

	if (!(mrioc->bsg_cmds.state & MPI3MR_CMD_COMPLETE)) {

Could the application thread assume the handler has fully finished, proceed
to read uninitialized reply memory, and free sense_buff_k before the interrupt
handler finishes copying into it? Would this result in a use-after-free when
the interrupt handler eventually executes the memcpy?

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

  reply	other threads:[~2026-08-18 18:14 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 [this message]
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
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=20260818181445.E16AC1F000E9@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