Linux SCSI subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Dave Marquardt" <davemarq@linux.ibm.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v4 1/8] ibmvfc: add basic FPIN support
Date: Fri, 10 Jul 2026 19:31:04 +0000	[thread overview]
Message-ID: <20260710193104.7DDBF1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260710-ibmvfc-fpin-support-v4-1-ef031ac19520@linux.ibm.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] Removal of `async->valid = 0;` leads to an infinite loop and stale message processing in the async CRQ tasklet.
- [High] Missing reference count acquisition on `tgt` in `ibmvfc_process_async_work` leads to Use-After-Free.
- [High] Improper devres lifecycle management of `fpin_workq` causes a double-free on probe failure and a Use-After-Free during device removal.
- [Medium] Data races and potential use-after-free in the new KUnit test module due to lockless access of global and host device lists.
--

--- Patch [1]: [PATCH v4 1/8] ibmvfc: add basic FPIN support ---
commit d8410cbccc8b5f74d804dc594b4dd758bd093c6e
Author: Dave Marquardt <davemarq@linux.ibm.com>

ibmvfc: add basic FPIN support

This patch implements basic Fabric Performance Impact Notifications (FPIN) 
support to enable monitoring of fabric congestion and link integrity events.
It adds async event handling that offloads FPIN processing to a workqueue
and introduces a KUnit test module for validation.

> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c

[ ... ]

> @@ -3185,16 +3189,228 @@ static const char *ibmvfc_get_link_state(enum ibmvfc_ae_link_state state)
> +static void ibmvfc_process_async_work(struct work_struct *work)
> +{

[ ... ]

> +	spin_lock_irqsave(vhost->host->host_lock, flags);
> +	list_for_each_entry_safe(tgt, next, &vhost->targets, queue) {
> +		if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) != crq->scsi_id)
> +			continue;
> +		if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) != crq->wwpn)
> +			continue;
> +		if (crq->node_name && cpu_to_be64(tgt->ids.node_name) != crq->node_name)
> +			continue;
> +		if (!tgt->rport)
> +			continue;
> +		break;
> +	}
> +	spin_unlock_irqrestore(vhost->host->host_lock, flags);
> +
> +	if (list_entry_is_head(tgt, &vhost->targets, queue) || !tgt->rport) {
> +		dev_err_ratelimited(vhost->dev, "Invalid target for FPIN\n");
> +		goto end;
> +	}
> +
> +	fpin = ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn);

[Severity: High]
Does this leave the target pointer vulnerable to a use-after-free?

The lock protecting the vhost->targets list is dropped before we access 
tgt->wwpn and tgt->rport, without acquiring a reference via kref_get().

If another thread handles a target logout or hotplug concurrently, it could 
remove and free the target structure, causing memory corruption when we 
attempt to access it here.

[ ... ]

> @@ -3803,8 +4031,6 @@ static void ibmvfc_tasklet(void *data)
>  		/* Pull all the valid messages off the async CRQ */
>  		while ((async = ibmvfc_next_async_crq(vhost)) != NULL) {
>  			ibmvfc_handle_async(async, vhost);
> -			async->valid = 0;
> -			wmb();
>  		}

[Severity: Critical]
Could removing this clearing operation lead to an infinite loop?

The hardware signals a valid entry by setting the valid field to 0x80. By 
removing the clearing of async->valid, the driver's ring-buffer polling logic 
will mistakenly see the old, uncleared entries as new valid entries once the 
circular queue index wraps around.

This would trap the system in an infinite loop within softirq context when 
processing any valid async event.

[ ... ]

> @@ -6364,9 +6588,15 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)

[ ... ]

> -	if ((rc = ibmvfc_alloc_mem(vhost)))
> +	vhost->fpin_workq = devm_alloc_workqueue(vhost->dev, "%s-fpin-workq-%u", 0, 0,
> +						 IBMVFC_NAME, shost->host_no);
> +	if (vhost->fpin_workq == NULL)
>  		goto free_scsi_host;

[ ... ]

> @@ -6412,6 +6642,9 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
>  	kthread_stop(vhost->work_thread);
>  free_host_mem:
>  	ibmvfc_free_mem(vhost);
> +free_workq:
> +	destroy_workqueue(vhost->fpin_workq);
> +	vhost->fpin_workq = NULL;

[Severity: High]
Can this result in a double-free on probe failure, and a use-after-free 
during device removal?

The workqueue is allocated using devm_alloc_workqueue(). On probe failure, 
destroy_workqueue() is called explicitly, and then devres will automatically 
call it again during cleanup, causing a double-free.

Additionally, during device removal in ibmvfc_remove(), the host is manually 
freed before devres automatically cleans up the workqueue. If there are 
pending work items like ibmvfc_process_async_work(), they will execute and 
attempt to dereference host pointers that have already been freed.

[ ... ]

> diff --git a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c
> --- /dev/null
> +++ b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c

[ ... ]

> +static void ibmvfc_async_fpin_test(struct kunit *test)
> +{

[ ... ]

> +	headp = ibmvfc_get_headp();
> +	if (list_empty(headp))
> +		kunit_skip(test, "No ibmvfc devices available");
> +	queue = headp->next;
> +	vhost = container_of(queue, struct ibmvfc_host, queue);
> +
> +	KUNIT_ASSERT_GE_MSG(test, vhost->num_targets, 1, "No targets");
> +	tgt = list_first_entry(&vhost->targets, struct ibmvfc_target, queue);

[Severity: Medium]
Is it safe to access the global ibmvfc_head list and vhost->targets list 
without holding the appropriate locks?

The test traverses the global ibmvfc_head without acquiring the 
ibmvfc_driver_lock, and then iterates over vhost->targets without acquiring 
the vhost->host->host_lock.

Since KUnit tests can run dynamically while other processes or the hypervisor 
interact with the driver, concurrently adding or removing devices could modify 
these lists and free structures, resulting in a use-after-free.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260710-ibmvfc-fpin-support-v4-0-ef031ac19520@linux.ibm.com?part=1

  reply	other threads:[~2026-07-10 19:31 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10 19:16 [PATCH v4 0/8] ibmvfc: make ibmvfc support FPIN messages Dave Marquardt via B4 Relay
2026-07-10 19:16 ` [PATCH v4 1/8] ibmvfc: add basic FPIN support Dave Marquardt via B4 Relay
2026-07-10 19:31   ` sashiko-bot [this message]
2026-07-10 19:16 ` [PATCH v4 2/8] ibmvfc: Add NOOP command support Dave Marquardt via B4 Relay
2026-07-10 19:31   ` sashiko-bot
2026-07-10 19:16 ` [PATCH v4 3/8] ibmvfc: make ibmvfc login to fabric Dave Marquardt via B4 Relay
2026-07-10 19:30   ` sashiko-bot
2026-07-10 19:16 ` [PATCH v4 4/8] ibmvfc: define asynchronous sub-queue Dave Marquardt via B4 Relay
2026-07-10 19:40   ` sashiko-bot
2026-07-10 19:16 ` [PATCH v4 5/8] ibmvfc: allocate " Dave Marquardt via B4 Relay
2026-07-10 19:36   ` sashiko-bot
2026-07-10 19:16 ` [PATCH v4 6/8] ibmvfc: extend async event handlers to handle async sub queue events Dave Marquardt via B4 Relay
2026-07-10 19:37   ` sashiko-bot
2026-07-10 19:16 ` [PATCH v4 7/8] ibmvfc: register and use asynchronous sub-queue for events Dave Marquardt via B4 Relay
2026-07-10 19:32   ` sashiko-bot
2026-07-10 19:16 ` [PATCH v4 8/8] ibmvfc: handle extended FPIN events Dave Marquardt via B4 Relay
2026-07-10 19:40   ` 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=20260710193104.7DDBF1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=davemarq@linux.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox