All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Justin Tee" <justintee8345@gmail.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v3 06/14] lpfc: Fix ndlp use-after-free during repeated RSCN and rediscovery sequence
Date: Tue, 14 Jul 2026 00:50:55 +0000	[thread overview]
Message-ID: <20260714005055.A6EE61F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260714011812.106753-7-justintee8345@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Race condition between `lpfc_unregister_remote_port` and `lpfc_dev_loss_tmo_callbk` leading to double-put and Use-After-Free.
- [High] Unbounded reference count leak for NVMe Target (NVMET) nodes during repeated RSCN rediscovery.
- [Medium] Lockless check in `lpfc_nlp_unreg_node` introduces a TOCTOU race leading to double unregistration.
--

--- Patch [6]: [PATCH v3 06/14] lpfc: Fix ndlp use-after-free during repeated RSCN and rediscovery sequence ---
commit a4e515a68e8dcd0a05052708ad0dbafb1627b3e9
Author: Justin Tee <justintee8345@gmail.com>
Subject: lpfc: Fix ndlp use-after-free during repeated RSCN and rediscovery sequence

This commit refactors lpfc_fc4_xpt_flags to use separate flags for SCSI
and NVME registrations. It adds wait flags to track unregister requests
during device loss and transport callbacks.

[ ... ]
> --- a/drivers/scsi/lpfc/lpfc_hbadisc.c
> +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
[ ... ]
> @@ -4562,6 +4556,7 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
>  {
>  	struct fc_rport *rport = ndlp->rport;
>  	struct lpfc_vport *vport = ndlp->vport;
> +	unsigned long flags;
>  
>  	if (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)
>  		return;
> @@ -4577,6 +4572,11 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
>  			 kref_read(&ndlp->kref));
>  
>  	fc_remote_port_delete(rport);
> +
> +	/* Flag unreg pending and reference released */
> +	spin_lock_irqsave(&ndlp->lock, flags);
> +	ndlp->fc4_xpt_flags |= SCSI_XPT_UNREG_WAIT;
> +	spin_unlock_irqrestore(&ndlp->lock, flags);
>  	lpfc_nlp_put(ndlp);
>  }

[Severity: High]
Can this sequence cause a double-put of the ndlp structure if the transport
callback races with this function?

Because SCSI_XPT_UNREG_WAIT is set after fc_remote_port_delete() is called,
the queued dev_loss_work task can execute asynchronously before the lock is
acquired here to set the wait flag.

If the transport callback wins the race, lpfc_dev_loss_tmo_callbk() will read
!(ndlp->fc4_xpt_flags & SCSI_XPT_UNREG_WAIT) as true, clear SCSI_XPT_REGD,
and call lpfc_nlp_put(). When lpfc_unregister_remote_port() resumes, it sets
the wait flag and unconditionally calls lpfc_nlp_put() again, which could
trigger a use-after-free.

[ ... ]
> @@ -4623,7 +4623,9 @@ lpfc_nlp_reg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
>  	lpfc_check_nlp_post_devloss(vport, ndlp);
>  
>  	spin_lock_irqsave(&ndlp->lock, iflags);
> -	if (ndlp->fc4_xpt_flags & NLP_XPT_REGD) {
> +	if ((ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD)) &&
> +	    !(ndlp->fc4_xpt_flags & (SCSI_XPT_UNREG_WAIT |
> +				     NVME_XPT_UNREG_WAIT))) {
>  		/* Already registered with backend, trigger rescan */
>  		spin_unlock_irqrestore(&ndlp->lock, iflags);

[Severity: High]
Does this code leak an ndlp reference for NVMe targets during repeated RSCN
rediscovery events?

In an NVMe target setup (nvmet_support != 0), neither SCSI_XPT_REGD nor
NVME_XPT_REGD is ever set. Instead, the code falls through to the target
handling block at the end of lpfc_nlp_reg_node():

        } else {
                /* Just take an NDLP ref count since the
                 * target does not register rports.
                 */
                lpfc_nlp_get(ndlp);
        }

Without a registration flag set, every subsequent call to lpfc_nlp_reg_node()
during repeated RSCNs will bypass this early return check, falling through to
execute lpfc_nlp_get() again and permanently leaking a reference each time.

[ ... ]
> @@ -4678,7 +4675,7 @@ lpfc_nlp_unreg_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
>  	unsigned long iflags;
>  
>  	spin_lock_irqsave(&ndlp->lock, iflags);
> -	if (!(ndlp->fc4_xpt_flags & NLP_XPT_REGD)) {
> +	if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) {
>  		spin_unlock_irqrestore(&ndlp->lock, iflags);
[ ... ]
>  	}
> -
> -	ndlp->fc4_xpt_flags &= ~NLP_XPT_REGD;
>  	spin_unlock_irqrestore(&ndlp->lock, iflags);
>  
>  	if (ndlp->rport &&
> -	    ndlp->fc4_xpt_flags & SCSI_XPT_REGD) {
> +	    ((ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | SCSI_XPT_UNREG_WAIT)) ==
> +	     SCSI_XPT_REGD)) {
>  		vport->phba->nport_event_cnt++;
>  		lpfc_unregister_remote_port(ndlp);

[Severity: Medium]
Could this lockless check introduce a time-of-check to time-of-use race?

The original code cleared NLP_XPT_REGD inside the ndlp->lock critical
section. By replacing it with a lockless check of the flag combination outside
the lock, two concurrent threads entering lpfc_nlp_unreg_node() could both
read the state as SCSI_XPT_REGD without SCSI_XPT_UNREG_WAIT.

If that happens, both threads would proceed to call
lpfc_unregister_remote_port(ndlp), leading to a double unregistration and
potential double-put of the ndlp structure.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260714011812.106753-1-justintee8345@gmail.com?part=6

  reply	other threads:[~2026-07-14  0:50 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14  1:17 [PATCH v3 00/14] Update lpfc to revision 15.0.0.1 Justin Tee
2026-07-14  1:17 ` [PATCH v3 01/14] lpfc: Fix use-after-free in lpfc_cmpl_ct_cmd_vmid Justin Tee
2026-07-14  0:51   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 02/14] lpfc: Early return out of lpfc_els_abort when HBA_SETUP flag is not set Justin Tee
2026-07-14  0:53   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 03/14] lpfc: Fix kernel oops when unmapping scsi dma buffers for an aborted cmd Justin Tee
2026-07-14  0:57   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 04/14] lpfc: Check fc4_xpt_flags before decrementing ndlp kref on FDISC error Justin Tee
2026-07-14  0:55   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 05/14] lpfc: Add handling for when PLOGI or PRLI is dropped during link failure Justin Tee
2026-07-14  1:02   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 06/14] lpfc: Fix ndlp use-after-free during repeated RSCN and rediscovery sequence Justin Tee
2026-07-14  0:50   ` sashiko-bot [this message]
2026-07-14  1:18 ` [PATCH v3 07/14] lpfc: Rework I/O flush ordering when unloading driver Justin Tee
2026-07-14  1:00   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 08/14] lpfc: Improve PLOGI retry handling for large SAN configurations Justin Tee
2026-07-14  0:55   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 09/14] lpfc: Send inhibited ABORT_WQE when PLOGI CQE SEQUENCE_TMO is received Justin Tee
2026-07-14  1:05   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 10/14] lpfc: Remove slowpath cqe process limiter in slow ring event handler Justin Tee
2026-07-14  0:54   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 11/14] lpfc: Put iocbq on phba->txq when ELS WQ is full or ELS SGL unavailable Justin Tee
2026-07-14  0:50   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 12/14] lpfc: Update ELS ACC logging for diagnostic troubleshooting Justin Tee
2026-07-14  1:02   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 13/14] lpfc: Refactor calls on fc_disctmo to lpfc_set_disctmo in RSCN handler Justin Tee
2026-07-14  1:00   ` sashiko-bot
2026-07-14  1:18 ` [PATCH v3 14/14] lpfc: Update lpfc version to 15.0.0.1 Justin Tee

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=20260714005055.A6EE61F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=justintee8345@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.