From: sashiko-bot@kernel.org
To: "Karl Mehltretter" <kmehltretter@gmail.com>
Cc: linux-s390@vger.kernel.org, kvm@vger.kernel.org,
"Heiko Carstens" <hca@linux.ibm.com>,
"Alexander Gordeev" <agordeev@linux.ibm.com>,
"Christian Borntraeger" <borntraeger@linux.ibm.com>,
linux-input@vger.kernel.org, dmitry.torokhov@gmail.com,
"Vasily Gorbik" <gor@linux.ibm.com>
Subject: Re: [PATCH v2 3/3] virtio: implement synchronize_cbs for remaining transports
Date: Sat, 05 Sep 2026 15:35:14 +0000 [thread overview]
Message-ID: <20260905153514.B55561F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260905152059.89560-4-kmehltretter@gmail.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [Medium] `virtio_vdpa_synchronize_cbs` fails to synchronize with the configuration callback, bypassing the synchronization mechanism entirely.
Pre-existing issues:
- [High] In remoteproc, virtqueues are freed without waiting for concurrent SRCU readers to finish, violating RCU-001 and leading to a Use-After-Free. Additionally, a TOCTOU vulnerability in `rproc_vq_interrupt` allows a NULL pointer dereference.
- [High] In TmFIFO, virtqueues are freed concurrently with an active background workqueue, leading to Use-After-Free. The synchronization added is inherently flawed and fails to wait for the workqueue.
--
commit 9ddf2954e77ee0736af8a3f1e37367f20723435b
Author: Karl Mehltretter <kmehltretter@gmail.com>
virtio: implement synchronize_cbs for remaining transports
virtio_reset_device() now calls synchronize_cbs to wait for running
callbacks. Its synchronize_rcu() fallback does not cover workqueue or
sleepable callbacks.
> diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c
> index 3c6408581373b..c260e3a1544ea 100644
> --- a/drivers/platform/mellanox/mlxbf-tmfifo.c
> +++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
[ ... ]
> @@ -1135,6 +1135,19 @@ static void mlxbf_tmfifo_virtio_reset(struct virtio_device *vdev)
> tm_vdev->status = 0;
> }
>
> +static void mlxbf_tmfifo_virtio_synchronize_cbs(struct virtio_device *vdev)
> +{
> + struct mlxbf_tmfifo_vdev *tm_vdev = mlxbf_vdev_to_tmfifo(vdev);
> + struct mlxbf_tmfifo *fifo = tm_vdev->vrings[0].fifo;
> + unsigned long flags;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(fifo->spin_lock); i++) {
> + spin_lock_irqsave(&fifo->spin_lock[i], flags);
> + spin_unlock_irqrestore(&fifo->spin_lock[i], flags);
> + }
> +}
[Severity: High]
This is a pre-existing issue, but does this sequential locking actually
synchronize anything? Acquiring and releasing locks one by one creates a race
window where callbacks can evade synchronization.
Additionally, does this fail to synchronize with the background workqueue
(fifo->work)? The workqueue function mlxbf_tmfifo_rxtx_one_desc()
dereferences vring->vq outside of the spinlocks.
When mlxbf_tmfifo_virtio_del_vqs() clears and frees the virtqueue, there is
a use-after-free risk because we haven't flushed the workqueue or properly
synchronized here.
[ ... ]
> diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
> index d5e9ff045a28a..ecc022e354db1 100644
> --- a/drivers/remoteproc/remoteproc_virtio.c
> +++ b/drivers/remoteproc/remoteproc_virtio.c
[ ... ]
> @@ -89,14 +90,19 @@ static bool rproc_virtio_notify(struct virtqueue *vq)
> irqreturn_t rproc_vq_interrupt(struct rproc *rproc, int notifyid)
> {
> struct rproc_vring *rvring;
> + int srcu_idx;
> + irqreturn_t ret;
> +
> + srcu_idx = srcu_read_lock(&rproc->vq_srcu);
>
> dev_dbg(&rproc->dev, "vq index %d is interrupted\n", notifyid);
>
> rvring = idr_find(&rproc->notifyids, notifyid);
> - if (!rvring || !rvring->vq)
> - return IRQ_NONE;
> + ret = rvring && rvring->vq ? vring_interrupt(0, rvring->vq) : IRQ_NONE;
[Severity: High]
This is a pre-existing issue, but doesn't this double evaluation of
rvring->vq introduce a Time-of-Check to Time-of-Use (TOCTOU) vulnerability?
Because READ_ONCE() is not used, the compiler could reload a NULL pointer if
__rproc_virtio_del_vqs() clears rvring->vq concurrently, leading to a NULL
pointer dereference when calling vring_interrupt().
> +
> + srcu_read_unlock(&rproc->vq_srcu, srcu_idx);
>
> - return vring_interrupt(0, rvring->vq);
> + return ret;
> }
> EXPORT_SYMBOL(rproc_vq_interrupt);
>
[ ... ]
> @@ -242,6 +248,13 @@ static void rproc_virtio_reset(struct virtio_device *vdev)
> dev_dbg(&vdev->dev, "reset !\n");
> }
>
> +static void rproc_virtio_synchronize_cbs(struct virtio_device *vdev)
> +{
> + struct rproc *rproc = vdev_to_rproc(vdev);
> +
> + synchronize_srcu(&rproc->vq_srcu);
> +}
[Severity: High]
This is a pre-existing issue, but virtqueues are freed without waiting for
concurrent SRCU readers to finish, violating the RCU-001 rule (Remove Before
Reclaim).
synchronize_srcu() is called here during device reset, but not during
teardown. In __rproc_virtio_del_vqs(), the virtqueue is removed and
immediately freed via vring_del_virtqueue() without a grace period.
Since the interrupt handler runs in an SRCU read-side critical section, can
this cause a use-after-free if vring_interrupt() executes on freed memory?
[ ... ]
> diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
> index de2af696de6ca..4f9e70c1332ef 100644
> --- a/drivers/virtio/virtio_vdpa.c
> +++ b/drivers/virtio/virtio_vdpa.c
[ ... ]
> @@ -123,8 +124,24 @@ static irqreturn_t virtio_vdpa_config_cb(void *private)
> static irqreturn_t virtio_vdpa_virtqueue_cb(void *private)
> {
> struct virtqueue *vq = private;
> + struct virtio_vdpa_device *vd_dev;
> + unsigned long flags;
> + irqreturn_t ret;
>
> - return vring_interrupt(0, vq);
> + vd_dev = to_virtio_vdpa_device(vq->vdev);
> + read_lock_irqsave(&vd_dev->callback_lock, flags);
> + ret = vring_interrupt(0, vq);
> + read_unlock_irqrestore(&vd_dev->callback_lock, flags);
> +
> + return ret;
> +}
[Severity: Medium]
While virtio_vdpa_virtqueue_cb() was updated to acquire callback_lock,
virtio_vdpa_config_cb() (just above this context in the file) was not.
Doesn't this mean virtio_vdpa_synchronize_cbs() fails to synchronize with
configuration changes, bypassing the synchronization mechanism if a config
change occurs concurrently with device reset or teardown?
> +
> +static void virtio_vdpa_synchronize_cbs(struct virtio_device *vdev)
> +{
> + struct virtio_vdpa_device *vd_dev = to_virtio_vdpa_device(vdev);
> +
> + write_lock_irq(&vd_dev->callback_lock);
> + write_unlock_irq(&vd_dev->callback_lock);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260905152059.89560-1-kmehltretter@gmail.com?part=3
prev parent reply other threads:[~2026-09-05 15:35 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-05 15:20 [PATCH v2 0/3] virtio: synchronize callbacks during device reset Karl Mehltretter
2026-09-05 15:20 ` [PATCH v2 1/3] " Karl Mehltretter
2026-09-05 15:35 ` sashiko-bot
2026-09-05 15:20 ` [PATCH v2 2/3] virtio_input: stop callbacks before unregistering input device Karl Mehltretter
2026-09-05 15:33 ` sashiko-bot
2026-09-05 15:20 ` [PATCH v2 3/3] virtio: implement synchronize_cbs for remaining transports Karl Mehltretter
2026-09-05 15:35 ` sashiko-bot [this message]
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=20260905153514.B55561F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=dmitry.torokhov@gmail.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=kmehltretter@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-s390@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