All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Tyrel Datwyler" <tyreld@linux.ibm.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH 21/29] ibmvfc: process NVMe/FC rports in work thread
Date: Tue, 23 Jun 2026 02:00:19 +0000	[thread overview]
Message-ID: <20260623020019.B216F1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260623013035.3436640-22-tyreld@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

New issues:
- [Critical] Deterministic NULL pointer dereference during NVMe remote port and local port unregistration.
- [High] NVMe targets marked for deletion are completely ignored by the main state machine, resulting in permanent resource leaks and stuck target states.
- [High] `ibmvfc_nvme_unregister` is dead code, permanently leaking the NVMe local port on module unload.

Pre-existing issues:
- [Critical] Concurrent target deletion during port addition completely leaks the newly registered remote port, leading to a Use-After-Free of the private data pointer for NVMe targets.
- [High] Target structures allocated from a mempool are incorrectly freed using `kfree()`, draining the mempool reserves and leading to hangs under memory pressure.
--

commit f73360d74019cb783c285fb8eef798a237334c34
Author: Tyrel Datwyler <tyreld@linux.ibm.com>

ibmvfc: process NVMe/FC rports in work thread

This commit adds an NVMe-specific remote-port add helper and updates
the rport worker thread to walk the NVMe target list. It handles
registration, rescan, and deletion transitions for NVMe remote
ports in the same worker context used for SCSI rports.

> diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ibmvfc-core.c
> --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
> +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
[ ... ]
> +static void ibmvfc_tgt_add_nvme_rport(struct ibmvfc_target *tgt)
> +{
> +	struct ibmvfc_host *vhost = tgt->vhost;
[ ... ]
> +	if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
> +		tgt_dbg(tgt, "Deleting NVMe rport\n");
> +		list_del(&tgt->queue);
> +		ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT);
> +		spin_unlock_irqrestore(vhost->host->host_lock, flags);
> +		ibmvfc_nvme_unregister_remoteport(tgt);

[Severity: Critical]
Does ibmvfc_nvme_unregister_remoteport() contain a null pointer dereference?

When unregistering the remote port, the completion callback appears to
explicitly set the tgt->nvme_remote_port pointer to NULL:

drivers/scsi/ibmvscsi/ibmvfc-nvme.c:ibmvfc_nvme_unregister_remoteport() {
    ...
    rc = nvme_fc_unregister_remoteport(tgt->nvme_remote_port);
    if (!rc) {
        wait_for_completion(&tgt->nvme_delete_done);
        tgt->nvme_remote_port->private = NULL;
    }
}

Will this attempt to dereference tgt->nvme_remote_port right after it was
set to NULL by ibmvfc_nvme_remoteport_delete before the completion signaled?
The same pattern seems to exist in ibmvfc_nvme_unregister() for the local
port.

> +		timer_delete_sync(&tgt->timer);
> +		kref_put(&tgt->kref, ibmvfc_release_tgt);

[Severity: High]
This is a pre-existing issue, but does ibmvfc_release_tgt() incorrectly free
mempool-allocated targets?

The targets are allocated via mempool_alloc(vhost->tgt_pool, GFP_NOIO) in
ibmvfc_alloc_targets(), but the kref release function calls kfree(tgt):

drivers/scsi/ibmvscsi/ibmvfc-core.c:ibmvfc_release_tgt() {
    struct ibmvfc_target *tgt = container_of(kref, struct ibmvfc_target, kref);
    kfree(tgt);
}

Does this bypass the mempool reserves and eventually cause mempool_alloc()
to hang under memory pressure?

> +		return;
> +	} else if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
[ ... ]
> +	} else if (rport && tgt->action == IBMVFC_TGT_ACTION_DELETED_RPORT) {
> +		spin_unlock_irqrestore(vhost->host->host_lock, flags);
> +		return;
> +	}

[Severity: Critical]
This is a pre-existing issue, but can this early return leak the newly
registered remote port?

If tgt->action is transitioned to IBMVFC_TGT_ACTION_DELETED_RPORT by the
state machine while the worker thread drops the lock to register the port,
we return early here without unregistering the newly created port.

For NVMe targets, tgt->nvme_remote_port->private points to the tgt
structure. If the tgt structure is subsequently freed via kref_put(), could
this cause a use-after-free in the NVMe midlayer when it uses the dangling
private data pointer?

[ ... ]
> @@ -6630,6 +6675,7 @@ static void ibmvfc_rport_add_thread(struct work_struct *work)
[ ... ]
> -	} while(did_work);
> +
> +		list_for_each_entry(tgt, &vhost->nvme_scrqs.targets, queue) {
> +			if (tgt->add_rport) {

[Severity: High]
Are NVMe targets marked for deletion completely ignored by the main state
machine?

The normal deletion path clears tgt->add_rport, which causes this worker
thread to ignore them. However, looking at the main state machine in
ibmvfc_do_work(), the deletion loop exists only for SCSI targets:

drivers/scsi/ibmvscsi/ibmvfc-core.c:ibmvfc_do_work() {
    ...
    list_for_each_entry(tgt, &vhost->scsi_scrqs.targets, queue) {
        if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
            ...
}

Since the equivalent loop is omitted for nvme_scrqs.targets, do targets
marked for deletion remain unlinked and permanently leaked?

[Severity: High]
On a related note, does the driver fail to unregister the NVMe local port on
module unload?

The teardown path in ibmvfc_remove() removes the SCSI host via
scsi_remove_host() but does not appear to invoke the NVMe equivalent logic.
There is an ibmvfc_nvme_unregister() function provided in the code, but it
seems to be completely dead code that is never called.

Could this lead to a permanent resource leak and potential use-after-free
in the NVMe midlayer if it interacts with the removed host?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260623013035.3436640-1-tyreld@linux.ibm.com?part=21

  reply	other threads:[~2026-06-23  2:00 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-23  1:30 [PATCH 00/29] ibmvfc: Add NVMe-FC support Tyrel Datwyler
2026-06-23  1:30 ` [PATCH 01/29] ibmvfc: move target list from host to protocol specific channel groups Tyrel Datwyler
2026-06-23  1:49   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 02/29] ibmvfc: add NVMe/FC protocol interface definitions Tyrel Datwyler
2026-06-23  1:54   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 03/29] ibmvfc: split NVMe support into separate source file and add transport stubs Tyrel Datwyler
2026-06-23  1:50   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 04/29] ibmvfc: initialize NVMe channel configuration during driver probe Tyrel Datwyler
2026-06-23  1:51   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 05/29] ibmvfc: alloc/dealloc sub-queues for nvme channels Tyrel Datwyler
2026-06-23  1:55   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 06/29] ibmvfc: add logic for protocol specific fabric logins Tyrel Datwyler
2026-06-23  1:50   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 07/29] ibmvfc: add wrapper to get vhost associated with a channel struct Tyrel Datwyler
2026-06-23  1:30 ` [PATCH 08/29] ibmvfc: add helper for creating protocol specific discovery event Tyrel Datwyler
2026-06-23  1:30 ` [PATCH 09/29] ibmvfc: add helper to check NVMe/FC support with active channels Tyrel Datwyler
2026-06-23  1:30 ` [PATCH 10/29] ibmvfc: allocate and free NVMe channel group discover buffer Tyrel Datwyler
2026-06-23  1:30 ` [PATCH 11/29] ibmvfc: send NVMe target discovery MAD Tyrel Datwyler
2026-06-23  1:52   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 12/29] ibmvfc: add NVMe/FC Implicit Logout and Move Login support Tyrel Datwyler
2026-06-23  1:49   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 13/29] ibmvfc: add NVMe/FC Port " Tyrel Datwyler
2026-06-23  1:53   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 14/29] ibmvfc: add NVMe/FC Process " Tyrel Datwyler
2026-06-23  1:52   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 15/29] ibmvfc: add NVMe/FC Query Target support Tyrel Datwyler
2026-06-23  1:52   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 16/29] ibmvfc: allocate targets based on protocol Tyrel Datwyler
2026-06-23  1:56   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 17/29] ibmvfc: delete NVMe/FC targets as well as SCSI Tyrel Datwyler
2026-06-23  1:51   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 18/29] ibmvfc: update state machine to process NVMe/FC targets Tyrel Datwyler
2026-06-23  1:55   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 19/29] ibmvfc: implement NVMe/FC stubs for local/remote port registration Tyrel Datwyler
2026-06-23  1:51   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 20/29] ibmvfc: register local nvme fc port after fabric login Tyrel Datwyler
2026-06-23  1:57   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 21/29] ibmvfc: process NVMe/FC rports in work thread Tyrel Datwyler
2026-06-23  2:00   ` sashiko-bot [this message]
2026-06-23  1:30 ` [PATCH 22/29] ibmvfc: extend ibmvfc_debug visibility to ibmvfc-nvme.h Tyrel Datwyler
2026-06-23  1:51   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 23/29] ibmvfc: declare global function definitions Tyrel Datwyler
2026-06-23  2:04   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 24/29] ibmvfc: implement LLDD callbacks for mapping nvme-fc queues Tyrel Datwyler
2026-06-23  2:05   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 25/29] ibmvfc: implement nvme-fc LS submission transport callback Tyrel Datwyler
2026-06-23  2:08   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 26/29] ibmvfc: implement nvme-fc IO command submission callback Tyrel Datwyler
2026-06-23  2:09   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 27/29] ibmvfc: implement nvme-fc LS abort handling callback Tyrel Datwyler
2026-06-23  2:09   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 28/29] ibmvfc: implement nvme-fc FCP abort callback Tyrel Datwyler
2026-06-23  2:05   ` sashiko-bot
2026-06-23  1:30 ` [PATCH 29/29] ibmvfc: fail nvme-fc fcp-io and ls requests during transport reset Tyrel Datwyler
2026-06-23  2:04   ` sashiko-bot

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=20260623020019.B216F1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=tyreld@linux.ibm.com \
    /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.