Linux SCSI subsystem development
 help / color / mirror / Atom feed
* [PATCH 6.6.y] scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
@ 2026-09-30  2:45 Artem Dinaburg
  2026-09-30  2:56 ` sashiko-bot
  2026-10-01 13:52 ` Sasha Levin
  0 siblings, 2 replies; 4+ messages in thread
From: Artem Dinaburg @ 2026-09-30  2:45 UTC (permalink / raw)
  To: stable
  Cc: Artem Dinaburg, Greg Kroah-Hartman, Sasha Levin, Justin Tee,
	Martin K. Petersen, James Smart, Dick Kennedy,
	James E.J. Bottomley, linux-scsi, linux-kernel, Paul Ely, jejb,
	martin.petersen

From: Justin Tee <justin.tee@broadcom.com>

[ Upstream commit ede596b1434b57c0b3fd5c02b326efe5c54f6e48 ]

The MBX_TIMEOUT return code is not handled in lpfc_get_sfp_info and the
routine unconditionally frees submitted mailbox commands regardless of
return status.  The issue is that for MBX_TIMEOUT cases, when firmware
returns SFP information at a later time, that same mailbox memory region
references previously freed memory in its cmpl routine.

Fix by adding checks for the MBX_TIMEOUT return code.  During mailbox
resource cleanup, check the mbox flag to make sure that the wait did not
timeout.  If the MBOX_WAKE flag is not set, then do not free the resources
because it will be freed when firmware completes the mailbox at a later
time in its cmpl routine.

Also, increase the timeout from 30 to 60 seconds to accommodate boot
scripts requiring longer timeouts.

[ Backport to 6.6.y: v6.6 predates ext_buf and uses ctx_buf for the SLI3
  raw payload. Restore ctx_buf to the saved struct lpfc_dmabuf before
  testing LPFC_MBX_WAKE so a timed-out mailbox's late default completion
  sees the DMA descriptor rather than payload bytes. ]

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20240628172011.25921-6-justintee8345@gmail.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Assisted-by: LLM
Signed-off-by: Artem Dinaburg <artem@trailofbits.com>
---
Hi Greg, Sasha, and scsi lpfc maintainers,

I am working through the small CVE backports still missing from 6.6.y.
This one addresses CVE-2024-46842. It leaves timed-out mailbox storage
alive for the eventual firmware completion.

The fix is already present in 6.12.y, 6.18.y, and 7.2.y, but not in 6.6.y.
The target-specific adjustment is recorded in the bracketed note above.
Unlike mainline, 6.6.y temporarily stores the SLI3 mailbox payload in
ctx_buf. Restoring the saved DMA descriptor before returning after a timeout
keeps the eventual firmware completion on the expected cleanup path.

Could you please queue it for 6.6.y?

CVE: CVE-2024-46842
Upstream: ede596b1434b57c0b3fd5c02b326efe5c54f6e48

AI assistance: An LLM helped identify, adapt, and validate this backport; I
reviewed the resulting code and validation evidence.

Thanks,
Artem Dinaburg

 drivers/scsi/lpfc/lpfc_els.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 2e9972a5878103..d319df7d36137c 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -7310,12 +7310,13 @@ int lpfc_get_sfp_info_wait(struct lpfc_hba *phba,
 	mbox->vport = phba->pport;
 	mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
 
-	rc = lpfc_sli_issue_mbox_wait(phba, mbox, 30);
+	rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_SLI4_CONFIG_TMO);
 	if (rc == MBX_NOT_FINISHED) {
 		rc = 1;
 		goto error;
 	}
-
+	if (rc == MBX_TIMEOUT)
+		goto error;
 	if (phba->sli_rev == LPFC_SLI_REV4)
 		mp = (struct lpfc_dmabuf *)(mbox->ctx_buf);
 	else
@@ -7367,9 +7368,11 @@ int lpfc_get_sfp_info_wait(struct lpfc_hba *phba,
 		mbox->u.mqe.un.mem_dump_type3.addr_lo = putPaddrLow(mp->phys);
 		mbox->u.mqe.un.mem_dump_type3.addr_hi = putPaddrHigh(mp->phys);
 	}
-
 	mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context;
-	rc = lpfc_sli_issue_mbox_wait(phba, mbox, 30);
+	rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_SLI4_CONFIG_TMO);
+
+	if (rc == MBX_TIMEOUT)
+		goto error;
 	if (bf_get(lpfc_mqe_status, &mbox->u.mqe)) {
 		rc = 1;
 		goto error;
@@ -7380,8 +7383,9 @@ int lpfc_get_sfp_info_wait(struct lpfc_hba *phba,
 			     DMP_SFF_PAGE_A2_SIZE);
 
 error:
 	mbox->ctx_buf = mpsave;
-	lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
+	if (mbox->mbox_flag & LPFC_MBX_WAKE)
+		lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
 
 	return rc;
 
-- 
2.39.5

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

* Re: [PATCH 6.6.y] scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
  2026-09-30  2:45 [PATCH 6.6.y] scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info Artem Dinaburg
@ 2026-09-30  2:56 ` sashiko-bot
  2026-10-01 13:52 ` Sasha Levin
  1 sibling, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-09-30  2:56 UTC (permalink / raw)
  To: Artem Dinaburg; +Cc: linux-scsi

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] scsi: lpfc: Use-After-Free and data race due to lockless mbox assignment
- [Medium] scsi: lpfc: memory leak of mbox and mpsave on synchronous issue failure
--

commit 7e8ff891a4886b3f83580607c0dc5ee36c6f7ce1
Author: Justin Tee <justin.tee@broadcom.com>

scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info

This commit adds checks for the MBX_TIMEOUT return code in lpfc_get_sfp_info,
avoiding unconditional frees of timed-out mailbox commands. The timeout is
also increased from 30 to 60 seconds to accommodate boot scripts.

Link: https://lore.kernel.org/r/20240628172011.25921-6-justintee8345@gmail.com

> diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
> index 2e9972a587810..d319df7d36137 100644
> --- a/drivers/scsi/lpfc/lpfc_els.c
> +++ b/drivers/scsi/lpfc/lpfc_els.c
> @@ -7381,7 +7384,8 @@ int lpfc_get_sfp_info_wait(struct lpfc_hba *phba,
>  
>  error:
>  	mbox->ctx_buf = mpsave;

[Severity: High]
If lpfc_sli_issue_mbox_wait() times out, it transfers ownership of the mailbox
by setting:

drivers/scsi/lpfc/lpfc_sli.c:lpfc_sli_issue_mbox_wait() {
    ...
    } else {
        retval = MBX_TIMEOUT;
        pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
    }
    ...
}

Does modifying mbox->ctx_buf locklessly here introduce a data race with the
asynchronous completion handler?

If the hardware completes the mailbox command and lpfc_sli_def_mbox_cmpl()
runs concurrently, could it read an invalid payload pointer leading to a crash
in lpfc_mbox_rsrc_cleanup(), or cause a use-after-free write on the freed
mbox struct?

> -	lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);
> +	if (mbox->mbox_flag & LPFC_MBX_WAKE)
> +		lpfc_mbox_rsrc_cleanup(phba, mbox, MBOX_THD_UNLOCKED);

[Severity: Medium]
When lpfc_sli_issue_mbox_wait() returns MBX_NOT_FINISHED, the LPFC_MBX_WAKE
flag is not set since the command failed to queue.

Will skipping lpfc_mbox_rsrc_cleanup() here leak the mbox and mpsave memory
on synchronous failures, since the async completion handler will never run to
clean them up?

>  	return rc;
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260930024505.96440-1-artem@trailofbits.com?part=1

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

* Re: [PATCH 6.6.y] scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
  2026-09-30  2:45 [PATCH 6.6.y] scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info Artem Dinaburg
  2026-09-30  2:56 ` sashiko-bot
@ 2026-10-01 13:52 ` Sasha Levin
  2026-10-02 17:50   ` Artem Dinaburg
  1 sibling, 1 reply; 4+ messages in thread
From: Sasha Levin @ 2026-10-01 13:52 UTC (permalink / raw)
  To: stable
  Cc: Sasha Levin, Artem Dinaburg, Greg Kroah-Hartman, Justin Tee,
	Martin K. Petersen, James Smart, Dick Kennedy,
	James E.J. Bottomley, linux-scsi, linux-kernel, Paul Ely, jejb,
	martin.petersen

> [ Backport to 6.6.y: v6.6 predates ext_buf and uses ctx_buf for the SLI3
>   raw payload. Restore ctx_buf to the saved struct lpfc_dmabuf before
>   testing LPFC_MBX_WAKE so a timed-out mailbox's late default completion
>   sees the DMA descriptor rather than payload bytes. ]

This isn't safe on SLI3 HBAs. When the new 60s wait times out, ctx_buf
is pointed back at mpsave, a 40-byte struct lpfc_dmabuf, while
out_ext_byte_len is still 256. If the firmware completes between 60s and
the 300s mailbox timeout, the SLI3 interrupt handler copies those 256
bytes into the dmabuf. That is a slab overflow, and lpfc_mbuf_free() then
runs on the corrupted virt/phys.

-- 
Thanks,
Sasha

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

* Re: [PATCH 6.6.y] scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
  2026-10-01 13:52 ` Sasha Levin
@ 2026-10-02 17:50   ` Artem Dinaburg
  0 siblings, 0 replies; 4+ messages in thread
From: Artem Dinaburg @ 2026-10-02 17:50 UTC (permalink / raw)
  To: Sasha Levin
  Cc: stable, Greg Kroah-Hartman, Justin Tee, Martin K. Petersen,
	James Smart, Dick Kennedy, James E.J. Bottomley, linux-scsi,
	linux-kernel, Paul Ely, jejb, martin.petersen

Hi Sasha,

Thanks for catching this.

I'm working on, and will send, a v2 addressing the issues.

While working on a fix, I also found what appears to be a separate
mailbox timeout/completion ownership race in both 6.6.y and current
mainline.

I do not have proper hardware to validate certainty, and can't emulate
it in QEMU, but I do have a hardware-independent KUnit test that
reproduces one of the failing interleavings. I'll send that separately
as an RFC to the LPFC/SCSI maintainers.

To be clear, v2 will not attempt to fix this newly identified
potential race. It will remain scoped to the existing backport and the
6.6-specific problems. If the RFC is accepted upstream, I can submit
its stable backport separately.

Thanks,
Artem Dinaburg

On Thu, Oct 1, 2026 at 9:52 AM Sasha Levin <sashal@kernel.org> wrote:
>
> > [ Backport to 6.6.y: v6.6 predates ext_buf and uses ctx_buf for the SLI3
> >   raw payload. Restore ctx_buf to the saved struct lpfc_dmabuf before
> >   testing LPFC_MBX_WAKE so a timed-out mailbox's late default completion
> >   sees the DMA descriptor rather than payload bytes. ]
>
> This isn't safe on SLI3 HBAs. When the new 60s wait times out, ctx_buf
> is pointed back at mpsave, a 40-byte struct lpfc_dmabuf, while
> out_ext_byte_len is still 256. If the firmware completes between 60s and
> the 300s mailbox timeout, the SLI3 interrupt handler copies those 256
> bytes into the dmabuf. That is a slab overflow, and lpfc_mbuf_free() then
> runs on the corrupted virt/phys.
>
> --
> Thanks,
> Sasha

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

end of thread, other threads:[~2026-10-02 17:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-30  2:45 [PATCH 6.6.y] scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info Artem Dinaburg
2026-09-30  2:56 ` sashiko-bot
2026-10-01 13:52 ` Sasha Levin
2026-10-02 17:50   ` Artem Dinaburg

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