From: Christian Schoenebeck <qemu_oss@crudebyte.com>
To: Stefano Stabellini <sstabellini@kernel.org>
Cc: qemu-devel@nongnu.org, qemu-stable@nongnu.org,
Greg Kurz <groug@kaod.org>,
Anthony PERARD <anthony@xenproject.org>,
"Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Subject: Re: [PATCH 3/3] hw/9pfs/xen: drain in-flight PDUs before xen-9p disconnect
Date: Sat, 18 Jul 2026 17:42:03 +0200 [thread overview]
Message-ID: <3351181.5fSG56mABF@weasel> (raw)
In-Reply-To: <alpine.DEB.2.22.394.2607171743150.16921@ubuntu-linux-20-04-desktop>
On Saturday, 18 July 2026 02:46:36 CEST Stefano Stabellini wrote:
> On Thu, 16 Jul 2026, Christian Schoenebeck wrote:
> > Hi Stefano,
> >
> > do you might have a chance to look at this Xen patch?
>
> Sorry for the delay
Thanks for looking at this, much appreciated!
> > On Thursday, 9 July 2026 15:50:36 CEST Christian Schoenebeck wrote:
> > > The xen-9p disconnect path has two issues:
> > >
> > > 1. It frees the Xen9pfsRing structures while in-flight PDUs may still
> > >
> > > reference them via pdu->tag to index rings[]. This causes a UAF
> > > in xen_9pfs_push_and_notify() when worker threads resume after
> > > completing filesystem operations.
> > >
> > > 2. It never calls v9fs_device_unrealize_common(), which means server
> > >
> > > state (struct LocalData, mountfd, FIDs) is never cleaned up on
> > > disconnect, causing a resource leak on every guest-initiated
> > > disconnect.
> > >
> > > Fix both by draining in-flight PDUs via v9fs_reset() before tearing
> > > down rings, and calling v9fs_device_unrealize_common() to clean up
> > > server state.
> > >
> > > Fixes: b37eeb0201 ("xen/9pfs: introduce Xen 9pfs backend")
> > > Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
> > > ---
> > >
> > > hw/9pfs/xen-9p-backend.c | 4 ++++
> > > 1 file changed, 4 insertions(+)
> > >
> > > diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c
> > > index 24c90d97ec..3b7a68779a 100644
> > > --- a/hw/9pfs/xen-9p-backend.c
> > > +++ b/hw/9pfs/xen-9p-backend.c
> > > @@ -368,10 +368,14 @@ static void xen_9pfs_evtchn_event(void *opaque)
> > >
> > > static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev)
> > > {
> > >
> > > Xen9pfsDev *xen_9pdev = container_of(xendev, Xen9pfsDev, xendev);
> > >
> > > + V9fsState *s = &xen_9pdev->state;
> > >
> > > int i;
> > >
> > > trace_xen_9pfs_disconnect(xendev->name);
> > >
> > > + v9fs_reset(s);
> > > + v9fs_device_unrealize_common(s);
>
> While the patch addresses a real issue, xen_9pfs_disconnect() is also
> called from the error paths of xen_9pfs_pdu_vmarshal/vunmarshal, which
> run inside the PDU's own coroutine. v9fs_reset() is not safe to be
> called there.
Well, xen_9pfs_pdu_vmarshal() / xen_9pfs_pdu_vunmarshal() are both called on
main thread, and xen_be_disconnect() has a guard that prevents the disconnect
handler being called twice (more about that later), however you are right that
these two functions run within coroutines. Which then leads to the following
problem in v9fs_reset():
while (!QLIST_EMPTY(&s->active_list)) {
aio_poll(qemu_get_aio_context(), true);
}
This loop would then run forever, as the coroutine calling v9fs_reset() is on
the active_list, hence this list would never turn empty and the loop condition
never turn false.
Furthermore aio_poll() is marked as no_coroutine_fn:
include/qemu/aio.h:bool no_coroutine_fn aio_poll(AioContext *ctx, bool
blocking);
So aio_poll() should actually not be called in a coroutine context at all.
> We could remove the direct call to xen_9pfs_disconnect() from
> xen_9pfs_pdu_vmarshal/vunmarshal because they already change the state
> to XenbusStateClosing, which should result in the same
The problem with this approach is that xen_9pfs_pdu_vmarshal() /
xen_9pfs_pdu_vunmarshal() would still call:
xen_be_set_state(&xen_9pfs->xendev, XenbusStateClosing);
And the previously mentioned guard in xen_be_disconnect() for not calling the
disconnect callback more than once, looks like this:
if (xendev->be_state != XenbusStateClosing &&
xendev->be_state != XenbusStateClosed &&
xendev->ops->disconnect) {
xendev->ops->disconnect(xendev);
}
Hence if this (v)unmarshal error path was triggered, the disconnect handler
would then actually never be executed. And that's apparently the reason why
these two functions do call xen_9pfs_disconnect() explicitly in their error
path right now.
What I think might work though, was replacing the current direct
xen_9pfs_disconnect() calls by deferred ones, something like:
aio_bh_schedule_oneshot(... xen_9pfs_disconnect ...);
Because xen_9pfs_disconnect() would then run both on main thread and not run
in a coroutine context. So it should turn it safe.
I'll prepare a v2 with the latter solution.
/Christian
next prev parent reply other threads:[~2026-07-18 15:42 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1783604079.git.qemu_oss@crudebyte.com>
2026-07-09 13:50 ` [PATCH 3/3] hw/9pfs/xen: drain in-flight PDUs before xen-9p disconnect Christian Schoenebeck
2026-07-16 12:32 ` Christian Schoenebeck
2026-07-18 0:46 ` Stefano Stabellini
2026-07-18 15:42 ` Christian Schoenebeck [this message]
2026-07-09 13:50 ` [PATCH 1/3] hw/9pfs/virtio: drain in-flight PDUs before virtio-9p unrealize Christian Schoenebeck
2026-07-09 14:20 ` Christian Schoenebeck
2026-07-10 1:39 ` m'te'a physical
2026-07-09 13:50 ` [PATCH 2/3] hw/9pfs/virtio: disable hotpluggable property of virtio-9p device Christian Schoenebeck
2026-07-10 7:37 ` Igor Mammedov
2026-07-10 8:06 ` Christian Schoenebeck
2026-07-10 10:23 ` Igor Mammedov
2026-07-10 10:49 ` Christian Schoenebeck
2026-07-10 12:51 ` Igor Mammedov
2026-07-10 14:31 ` Christian Schoenebeck
2026-07-10 14:40 ` Daniel P. Berrangé
2026-07-13 7:49 ` Igor Mammedov
2026-07-17 14:05 ` Christian Schoenebeck
2026-07-17 14:16 ` Daniel P. Berrangé
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=3351181.5fSG56mABF@weasel \
--to=qemu_oss@crudebyte.com \
--cc=anthony@xenproject.org \
--cc=edgar.iglesias@gmail.com \
--cc=groug@kaod.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-stable@nongnu.org \
--cc=sstabellini@kernel.org \
/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.