Re: [PATCH] scsi: lpfc: fix heap overflow in lpfc_bsg_diag_loopback_run()
From: James Bottomley
Date: Wed Apr 22 2026 - 09:29:55 EST
On Wed, 2026-04-22 at 17:18 +0800, Junrui Luo wrote:
> lpfc_bsg_diag_loopback_run() allocates dataout as a staging buffer
> before copying loopback test data into DMA segments. When the
> user-supplied payload size exceeds 64KB, the allocation is capped at
> 64KB while sg_copy_to_buffer() and the subsequent memcpy loop operate
> on the full payload (up to 80 * 4096 bytes).
Are you sure? The comment above the code you're changing says:
/*
* Allocate memory for ioctl data. If buffer is bigger than 64k,
* then we allocate 64k and re-use that buffer over and over to
* xfer the whole block. This is because Linux kernel has a
* problem allocating more than 120k of kernel space memory. Saw
* problem with GET_FCPTARGETMAPPING...
*/
Which implies the intention is to allocate only 64kb if the payload
exceeds that and break the work into 64kb or less sized chunks. So if
there is a problem here, it sounds like the loop over 64k chunks would
need fixing rather than the allocation.
>
> This leads to a heap buffer overflow with user-controlled data.
>
> Fix by allocating full_size in the large-size path, consistent with
> the small-size path and with diag_cmd_data_alloc().
>
> Fixes: 3b5dd52aaffd ("[SCSI] lpfc 8.3.8: (BSG4) Add new vendor
> specific BSG Commands")
> Reported-by: Yuhao Jiang <danisjiang@xxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Junrui Luo <moonafterrain@xxxxxxxxxxx>
> ---
> drivers/scsi/lpfc/lpfc_bsg.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/lpfc/lpfc_bsg.c
> b/drivers/scsi/lpfc/lpfc_bsg.c
> index 7406dfa60016..83fef256f324 100644
> --- a/drivers/scsi/lpfc/lpfc_bsg.c
> +++ b/drivers/scsi/lpfc/lpfc_bsg.c
> @@ -3111,7 +3111,7 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job)
> if (size <= (64 * 1024))
> total_mem = full_size;
> else
> - total_mem = 64 * 1024;
> + total_mem = full_size;
This would render the if clause useless because the branches have the
same statement.
Regards,
James