Skip to content

Commit 49d1189

Browse files
committed
scsi: lpfc: Fix buffer free/clear order in deferred receive path
jira VULN-156034 cve CVE-2025-39841 commit-author John Evans <[email protected]> commit 9dba9a4 Fix a use-after-free window by correcting the buffer release sequence in the deferred receive path. The code freed the RQ buffer first and only then cleared the context pointer under the lock. Concurrent paths (e.g., ABTS and the repost path) also inspect and release the same pointer under the lock, so the old order could lead to double-free/UAF. Note that the repost path already uses the correct pattern: detach the pointer under the lock, then free it after dropping the lock. The deferred path should do the same. Fixes: 472e146 ("scsi: lpfc: Correct upcalling nvmet_fc transport during io done downcall") Cc: [email protected] Signed-off-by: John Evans <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Justin Tee <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]> (cherry picked from commit 9dba9a4) Signed-off-by: Roxana Nicolescu <[email protected]>
1 parent 9c93236 commit 49d1189

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

drivers/scsi/lpfc/lpfc_nvmet.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,31 +1245,33 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport,
12451245
struct lpfc_nvmet_tgtport *tgtp;
12461246
struct lpfc_async_xchg_ctx *ctxp =
12471247
container_of(rsp, struct lpfc_async_xchg_ctx, hdlrctx.fcp_req);
1248-
struct rqb_dmabuf *nvmebuf = ctxp->rqb_buffer;
1248+
struct rqb_dmabuf *nvmebuf;
12491249
struct lpfc_hba *phba = ctxp->phba;
12501250
unsigned long iflag;
12511251

12521252

12531253
lpfc_nvmeio_data(phba, "NVMET DEFERRCV: xri x%x sz %d CPU %02x\n",
12541254
ctxp->oxid, ctxp->size, raw_smp_processor_id());
12551255

1256+
spin_lock_irqsave(&ctxp->ctxlock, iflag);
1257+
nvmebuf = ctxp->rqb_buffer;
12561258
if (!nvmebuf) {
1259+
spin_unlock_irqrestore(&ctxp->ctxlock, iflag);
12571260
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_IOERR,
12581261
"6425 Defer rcv: no buffer oxid x%x: "
12591262
"flg %x ste %x\n",
12601263
ctxp->oxid, ctxp->flag, ctxp->state);
12611264
return;
12621265
}
1266+
ctxp->rqb_buffer = NULL;
1267+
spin_unlock_irqrestore(&ctxp->ctxlock, iflag);
12631268

12641269
tgtp = phba->targetport->private;
12651270
if (tgtp)
12661271
atomic_inc(&tgtp->rcv_fcp_cmd_defer);
12671272

12681273
/* Free the nvmebuf since a new buffer already replaced it */
12691274
nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf);
1270-
spin_lock_irqsave(&ctxp->ctxlock, iflag);
1271-
ctxp->rqb_buffer = NULL;
1272-
spin_unlock_irqrestore(&ctxp->ctxlock, iflag);
12731275
}
12741276

12751277
/**

0 commit comments

Comments
 (0)