[PATCH] scsi: lpfc: Fix use-after-free in lpfc_els_rsp_rls_acc()

Wentao Liang posted 1 patch 1 week ago
drivers/scsi/lpfc/lpfc_els.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
[PATCH] scsi: lpfc: Fix use-after-free in lpfc_els_rsp_rls_acc()
Posted by Wentao Liang 1 week ago
lpfc_els_rsp_rls_acc() drops the ndlp reference held for the
MBX_READ_LNK_STAT mailbox command before it logs the ACC response and
before it takes the reference that keeps the node alive while the
response is being sent.  If that was the last reference, ndlp is freed
and the log message and lpfc_nlp_get() below touch released memory.

Take the reference for the ACC iocb before dropping the mailbox one.

Fixes: 12265f68ae92 ("[SCSI] lpfc 8.3.18: Add support of received ELS commands")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
---
 drivers/scsi/lpfc/lpfc_els.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 4e3fe89283e4..bdf8fe3e77a5 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -8782,11 +8782,9 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 				     lpfc_max_els_tries, ndlp,
 				     ndlp->nlp_DID, ELS_CMD_ACC);
 
-	/* Decrement the ndlp reference count from previous mbox command */
-	lpfc_nlp_put(ndlp);
-
 	if (!elsiocb) {
 		mempool_free(pmb, phba->mbox_mem_pool);
+		lpfc_nlp_put(ndlp);
 		return;
 	}
 
@@ -8824,6 +8822,10 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 	elsiocb->cmd_cmpl = lpfc_cmpl_els_rsp;
 	phba->fc_stat.elsXmitACC++;
 	elsiocb->ndlp = lpfc_nlp_get(ndlp);
+
+	/* Decrement the ndlp reference count from previous mbox command */
+	lpfc_nlp_put(ndlp);
+
 	if (!elsiocb->ndlp) {
 		lpfc_els_free_iocb(phba, elsiocb);
 		return;
-- 
2.34.1
Re: [PATCH] scsi: lpfc: Fix use-after-free in lpfc_els_rsp_rls_acc()
Posted by Paul Ely 1 week ago
The ndlp has an initial reference when first allocated and the
lpfc_nlp_put moved is for the outstanding LNK mailbox.  Unless there
is a driver bug with premature puts on the ndlp, this bug can't really
happen.
I would like to test this change before Acking it.

Thanks.


On Thu, Sep 17, 2026 at 10:44 AM Wentao Liang <vulab@iscas.ac.cn> wrote:
>
> lpfc_els_rsp_rls_acc() drops the ndlp reference held for the
> MBX_READ_LNK_STAT mailbox command before it logs the ACC response and
> before it takes the reference that keeps the node alive while the
> response is being sent.  If that was the last reference, ndlp is freed
> and the log message and lpfc_nlp_get() below touch released memory.
>
> Take the reference for the ACC iocb before dropping the mailbox one.
>
> Fixes: 12265f68ae92 ("[SCSI] lpfc 8.3.18: Add support of received ELS commands")
> Cc: stable@vger.kernel.org
> Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
> ---
>  drivers/scsi/lpfc/lpfc_els.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
> index 4e3fe89283e4..bdf8fe3e77a5 100644
> --- a/drivers/scsi/lpfc/lpfc_els.c
> +++ b/drivers/scsi/lpfc/lpfc_els.c
> @@ -8782,11 +8782,9 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
>                                      lpfc_max_els_tries, ndlp,
>                                      ndlp->nlp_DID, ELS_CMD_ACC);
>
> -       /* Decrement the ndlp reference count from previous mbox command */
> -       lpfc_nlp_put(ndlp);
> -
>         if (!elsiocb) {
>                 mempool_free(pmb, phba->mbox_mem_pool);
> +               lpfc_nlp_put(ndlp);
>                 return;
>         }
>
> @@ -8824,6 +8822,10 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
>         elsiocb->cmd_cmpl = lpfc_cmpl_els_rsp;
>         phba->fc_stat.elsXmitACC++;
>         elsiocb->ndlp = lpfc_nlp_get(ndlp);
> +
> +       /* Decrement the ndlp reference count from previous mbox command */
> +       lpfc_nlp_put(ndlp);
> +
>         if (!elsiocb->ndlp) {
>                 lpfc_els_free_iocb(phba, elsiocb);
>                 return;
> --
> 2.34.1
>
Re: [PATCH] scsi: lpfc: Fix use-after-free in lpfc_els_rsp_rls_acc()
Posted by Paul Ely 1 week ago
Fixing bad email address list.

On Thu, Sep 17, 2026 at 3:32 PM Paul Ely <paul.ely@broadcom.com> wrote:
>
> The ndlp has an initial reference when first allocated and the
> lpfc_nlp_put moved is for the outstanding LNK mailbox.  Unless there
> is a driver bug with premature puts on the ndlp, this bug can't really
> happen.
> I would like to test this change before Acking it.
>
> Thanks.
>
>
> On Thu, Sep 17, 2026 at 10:44 AM Wentao Liang <vulab@iscas.ac.cn> wrote:
> >
> > lpfc_els_rsp_rls_acc() drops the ndlp reference held for the
> > MBX_READ_LNK_STAT mailbox command before it logs the ACC response and
> > before it takes the reference that keeps the node alive while the
> > response is being sent.  If that was the last reference, ndlp is freed
> > and the log message and lpfc_nlp_get() below touch released memory.
> >
> > Take the reference for the ACC iocb before dropping the mailbox one.
> >
> > Fixes: 12265f68ae92 ("[SCSI] lpfc 8.3.18: Add support of received ELS commands")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
> > ---
> >  drivers/scsi/lpfc/lpfc_els.c | 8 +++++---
> >  1 file changed, 5 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
> > index 4e3fe89283e4..bdf8fe3e77a5 100644
> > --- a/drivers/scsi/lpfc/lpfc_els.c
> > +++ b/drivers/scsi/lpfc/lpfc_els.c
> > @@ -8782,11 +8782,9 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
> >                                      lpfc_max_els_tries, ndlp,
> >                                      ndlp->nlp_DID, ELS_CMD_ACC);
> >
> > -       /* Decrement the ndlp reference count from previous mbox command */
> > -       lpfc_nlp_put(ndlp);
> > -
> >         if (!elsiocb) {
> >                 mempool_free(pmb, phba->mbox_mem_pool);
> > +               lpfc_nlp_put(ndlp);
> >                 return;
> >         }
> >
> > @@ -8824,6 +8822,10 @@ lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
> >         elsiocb->cmd_cmpl = lpfc_cmpl_els_rsp;
> >         phba->fc_stat.elsXmitACC++;
> >         elsiocb->ndlp = lpfc_nlp_get(ndlp);
> > +
> > +       /* Decrement the ndlp reference count from previous mbox command */
> > +       lpfc_nlp_put(ndlp);
> > +
> >         if (!elsiocb->ndlp) {
> >                 lpfc_els_free_iocb(phba, elsiocb);
> >                 return;
> > --
> > 2.34.1
> >