From: sashiko-bot@kernel.org
To: "João Peixoto" <jpeixoto@osyx.tech>
Cc: devicetree@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v6 2/3] virt: bao: add I/O dispatcher driver
Date: Fri, 13 Nov 2026 17:27:20 +0000 [thread overview]
Message-ID: <sashiko-outbox-213306@kernel.org> (raw)
In-Reply-To: <4e725d9d94cfd425ac0ff4352b21f7bf7b7a1296.1794589639.git.jpeixoto@osyx.tech>
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] virt: bao: race in bao_irqfd_queue_shutdown() causes UAF on
teardown
--
commit a54931ee06339bcb9128b2ac3b46c8d5cb3569c1
Author: João Peixoto <jpeixoto@osyx.tech>
virt: bao: add I/O dispatcher driver
This commit adds the Bao hypervisor I/O dispatcher driver, exposing
/dev/bao and per-DM file descriptors to bridge Remote I/O requests,
shared memory, ioeventfds, and irqfds between frontend guests and
userspace VirtIO device models.
> diff --git a/drivers/virt/bao/io-dispatcher/irqfd.c b/drivers/virt/bao/io-dispatcher/irqfd.c
> new file mode 100644
> index 0000000000000..8d01bef4e7abd
> --- /dev/null
> +++ b/drivers/virt/bao/io-dispatcher/irqfd.c
> @@ -0,0 +1,330 @@
[ ... ]
> +/* Queue the cleanup work at most once. Safe from atomic context. */
> +static void bao_irqfd_queue_shutdown(struct irqfd *irqfd)
> +{
> + if (!test_and_set_bit(BAO_IRQFD_SHUTDOWN, &irqfd->flags))
> + queue_work(irqfd->dm->irqfd_server, &irqfd->shutdown);
> +}
[ ... ]
> +static int bao_irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode,
> + int sync, void *key)
> +{
> + struct irqfd *irqfd = container_of(wait, struct irqfd, wait);
> + __poll_t flags = key_to_poll(key);
> + u64 cnt;
> +
> + if (flags & EPOLLIN) {
> + eventfd_ctx_do_read(irqfd->eventfd, &cnt);
> + bao_irqfd_inject(irqfd->dm->info.id);
> + }
> +
> + if (flags & EPOLLHUP)
> + /* Defer teardown to the cleanup work; can't sleep here. */
> + bao_irqfd_queue_shutdown(irqfd);
> +
> + return 0;
> +}
[ ... ]
> +void bao_irqfd_server_destroy(struct bao_dm *dm)
> +{
> + struct irqfd *irqfd;
> + struct irqfd *next;
> +
> + if (WARN_ON_ONCE(!dm))
> + return;
> +
> + mutex_lock(&dm->irqfds_lock);
> + list_for_each_entry_safe(irqfd, next, &dm->irqfds, list) {
> + list_del_init(&irqfd->list);
> + dm->nr_irqfds--;
> + bao_irqfd_queue_shutdown(irqfd);
> + }
> + mutex_unlock(&dm->irqfds_lock);
> +
> + /* Drain all cleanup work before tearing the workqueue down. */
> + if (dm->irqfd_server) {
> + flush_workqueue(dm->irqfd_server);
> + destroy_workqueue(dm->irqfd_server);
> + }
> +}
[Severity: Medium]
Can bao_irqfd_queue_shutdown() race with bao_irqfd_server_destroy() and
cause a use-after-free of dm and dm->irqfd_server?
bao_irqfd_wakeup() runs on EPOLLHUP without holding dm->irqfds_lock. Once
it sets BAO_IRQFD_SHUTDOWN in bao_irqfd_queue_shutdown(), a concurrent
teardown caller sees the bit already set and moves on to flush and destroy
dm->irqfd_server before the work item is actually queued:
CPU0 CPU1
eventfd_release() bao_dm_release()
wake_up_poll(..., EPOLLHUP) bao_dm_destroy()
bao_irqfd_wakeup() bao_irqfd_server_destroy()
bao_irqfd_queue_shutdown() mutex_lock(&dm->irqfds_lock)
test_and_set_bit(...) -> 0 bao_irqfd_queue_shutdown()
test_and_set_bit(...) -> 1
mutex_unlock(&dm->irqfds_lock)
flush_workqueue(dm->irqfd_server)
destroy_workqueue(dm->irqfd_server)
kfree(dm)
queue_work(irqfd->dm->irqfd_server, ...)
<-- use-after-free
The same race with bao_irqfd_deassign() lets flush_workqueue() return
before irqfd->shutdown has been queued and run.
Since queue_work() already ignores a work_struct that is currently
pending, bao_irqfd_queue_shutdown() can call queue_work() unconditionally
without BAO_IRQFD_SHUTDOWN so that both paths guarantee the work is queued
before returning.
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1794589639.git.jpeixoto@osyx.tech?part=2
next prev parent reply other threads:[~2026-11-13 17:27 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-13 17:12 [PATCH v6 0/3] virt: bao: add Bao hypervisor IPC and I/O dispatcher drivers João Peixoto
2026-11-13 17:12 ` João Peixoto
2026-11-13 17:12 ` [PATCH v6 1/3] virt: bao: add IPC shared-memory driver João Peixoto
2026-11-13 17:12 ` João Peixoto
2026-11-13 17:12 ` [PATCH v6 2/3] virt: bao: add I/O dispatcher driver João Peixoto
2026-11-13 17:12 ` João Peixoto
2026-11-13 17:27 ` sashiko-bot [this message]
2026-11-13 17:12 ` [PATCH v6 3/3] MAINTAINERS: add Bao hypervisor entry João Peixoto
2026-11-13 17:12 ` João Peixoto
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=sashiko-outbox-213306@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=jpeixoto@osyx.tech \
--cc=robh@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.