From nobody Sat Jul 25 06:37:08 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=crudebyte.com ARC-Seal: i=1; a=rsa-sha256; t=1784810900; cv=none; d=zohomail.com; s=zohoarc; b=YPhIxAcgX7IRMpt7NzWFk5OKaM6jY9FkXM0Ksa2Iu5AhhCURSKV+vh5lhJwa5I+zP/rNQwOT33ltZfZMxYNjhedBgY7fWImHeh0FYq7p3WkKc8EPUdhFXKWoC8AHU4S2pu28RBJj71CtD/eVQ9ofmnD4ug0RanMvhdA6BQz5l2U= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784810900; h=Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=TnTyMGcps9pLzVD+xAJmeZIkZhLzfTw6EtxKWuY+Rlk=; b=Aq395oqExphnvJCfSmLTPffWghPmbwQg4rXGmbXPJsm/dwqRfqDxIae0X5zosazVKKRI4Ye/JBZCXutjTh/sqC9ETE+koCKSUkIqq3nRktMtfQg7Mkk7QoZDHHnFWtqdhAjUzyhLp0usRknKHDg5K1il6eY7Z/k9DGoPuZdSgxo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784810900309347.80538024866473; Thu, 23 Jul 2026 05:48:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmsq6-0008QE-J5; Thu, 23 Jul 2026 08:47:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmsq5-0008Pb-1Z; Thu, 23 Jul 2026 08:47:49 -0400 Received: from kylie.crudebyte.com ([5.189.157.229]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wmsq3-0001At-Hx; Thu, 23 Jul 2026 08:47:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=crudebyte.com; s=kylie; h=Cc:To:Subject:Date:From:References:In-Reply-To: Message-ID:Content-Type:Content-Transfer-Encoding:MIME-Version:Content-ID: Content-Description; bh=TnTyMGcps9pLzVD+xAJmeZIkZhLzfTw6EtxKWuY+Rlk=; b=em81i e1qWzqIhGv409/7mFWtZTK9XGcBCXAUFM9qrFS4WaVHA/Pt9s8gLiNSOVAcqfZW4Y4P6BIKPd7vB5 ufPTFP5S/qiCnH6Vd7OSmp61FWcHguMHIQaLSrlz/DR30WceAKz9elIKRomfsvGv6isFC1Np1bt0e +LXE4JutFmuWBOCZtNcJe7Zx8hjwJYlLUWfFkhzCAAZT6ee05kbfHvEOgP5lHHQ9QtXdGheQMOR2S nDn0ULrFVvK0LKfHoIB9FnxO+rswDiztqhT+ErhYfnvBpvv/LaHujvOo3Koj4hkF1rB9QWr5BNYeQ /E40+JvbnFZBaKmT6P9DXY1b1EE9KQjnQWy9Pxdacp++YeVbh4XKe0ISQFwzS7ANiWos/y8jjFuwY lvgyJXDewjWhZidBo9ERUHCKD+HO0K/9tGPWY8qRb3Lc9vEIXU1SRulpwpJ1ob/AyfSMrmdBPSMzF 5XC2kmC67QGdHjfH9KXgtJjoYrA3oHft7v1jIMaW80mAu0YFgGbJxykY67SMFV0kUAjOYowPqNpzI INDSHl5PULp1t8qC6ZvyxSJaRUw/lRyc20ECTP2b0oCugx7zSmuU3N2hGS8iy3w1y9itnN15m+sOf ESgiQgwigC/jk4C/xOdHNdTJT79uPoXNphpHdtW6vzXx+qkJJ9Zf6/fgasl9vA=; Message-ID: In-Reply-To: References: From: Christian Schoenebeck Date: Thu, 23 Jul 2026 14:43:24 +0200 Subject: [PATCH v3 1/2] hw/9pfs/virtio: drain in-flight PDUs before virtio-9p unrealize To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, Greg Kurz , Jia Jia Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=5.189.157.229; envelope-from=bc503aefffd20b1806941b3ef708afbd92f0aef2@kylie.crudebyte.com; helo=kylie.crudebyte.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @crudebyte.com) X-ZM-MESSAGEID: 1784810902514158500 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Jia Jia A guest can trigger a heap-use-after-free in the virtio transport unrealize path by submitting a Treaddir request and immediately ejecting the device via ACPI PCI hotplug. The unrealize path frees struct LocalData while a worker thread still holds a reference on it, causing a UAF in local_open_nofollow(). Fix this by draining all in-flight 9p PDUs by calling v9fs_reset() before final server cleanup. This ensures all coroutines completed, all FIDs are closed, and no worker thread still holds references on 9p server state when it is freed. Fixes: 6cecf09373 ("virtio-9p-device: add minimal unrealize handler") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3937 Signed-off-by: Jia Jia [ Christian Schoenebeck: add commit log message. ] Signed-off-by: Christian Schoenebeck --- hw/9pfs/virtio-9p-device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index 50dc93091d..1ec48fc9e0 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -243,6 +243,7 @@ static void virtio_9p_device_unrealize(DeviceState *dev) V9fsVirtioState *v =3D VIRTIO_9P(dev); V9fsState *s =3D &v->state; =20 + v9fs_reset(s); virtio_delete_queue(v->vq); virtio_cleanup(vdev); v9fs_device_unrealize_common(s); --=20 2.47.3 From nobody Sat Jul 25 06:37:08 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=crudebyte.com ARC-Seal: i=1; a=rsa-sha256; t=1784810888; cv=none; d=zohomail.com; s=zohoarc; b=fXi3a9W/QtDdao96RjpH45sE9/eRAnIDL06YttPYckTLgSPFhSJnc/QI9FhSc4WS4byX3K5sUyH6Pi+lE820Ou0dLp0VRWrlzuyXzil2IQyW/YnltSoRUPFC5StG/bJuqkjRjtRfUJdhVNbdh4/PY66XFo7PJJfPdnNlp9IuKJA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1784810888; h=Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=5s4DKpC1T0PeqN+HSt0e5weoQMg0AJgXHQ4lDgYkK8g=; b=YFAxURSt5gUCC8l8WifUpKabzvCwaP5k7RKFcMSs+AG/ErMKFYtJNQ0vGq/yMa3Gm28RYBPvLqz8mAYC1oblfu+q7aL11+/C04qjBVNYJ/l32oP1XAoYfFVAyP8b9yjpM2Km5bU/5kdN72Sc073I42A6wDM2EMuyQ8DRL6rwwIY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1784810888227559.5247269731564; Thu, 23 Jul 2026 05:48:08 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wmsq6-0008QQ-Vc; Thu, 23 Jul 2026 08:47:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <82bc736158e827e05d4b55da27c39d42e2062e96@kylie.crudebyte.com>) id 1wmsq5-0008Pr-BN; Thu, 23 Jul 2026 08:47:49 -0400 Received: from kylie.crudebyte.com ([5.189.157.229]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from <82bc736158e827e05d4b55da27c39d42e2062e96@kylie.crudebyte.com>) id 1wmsq3-0001BP-Lr; Thu, 23 Jul 2026 08:47:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=crudebyte.com; s=kylie; h=Cc:To:Subject:Date:From:References:In-Reply-To: Message-ID:Content-Type:Content-Transfer-Encoding:MIME-Version:Content-ID: Content-Description; bh=5s4DKpC1T0PeqN+HSt0e5weoQMg0AJgXHQ4lDgYkK8g=; b=LQx6M bbmcCxGkeHm/6RlU03Co+kEysM8bd4y2gvK940DACKFRw+Mw+DzIhjyBc7aY8e+pDHOCYd2ckk9JE xeQFaCtY7LJhi4V11oBZVmcxuPvGdg7TH5i1Z4qv4hJDSkfUkh0FCNPHnNLXFcVwAXAx6u8w+SWla O1RhvoR6nu6ZP1zylX+nfUuhzUQo4zZtfbPu0CvJxa7Z/VbFAuXYwGa2548Y3poxd/JW2SEPZXk7t 5ZuXvDQMX4sqJdc2fJcRDugwRN0mJEzG3Iy6IIjvdrYgdJWXTpmMrTDHjTZOFRXLmjIXgKvJI6qF5 lPwPI3JJox1dG8WussmPROJviVQL5AwjLS4Zxh5JdIs7tcKQLipCTrnJIZpwAD+tuTkCRPa05AfmR pobj+zw9Q4vadtkCsnmZlVxzUjKU5sze3BF7wPQ5eMSUohMBLbzwWfc8LmZsmDol5PvpDPzYExgPy LFNKu7kbuLK+fhmHP7zv6vY5cgeKA1IfZbgTpczzlRgBCGw45VKknokkiHgn5/PLgpv72yVF2qkFr 3I1okD6QFMS9ehTjZkXw722+j/IrQNA3QYjvxlhxmomUuKs2ME71pMtchgfpZxmqr+q1nCT7efAEw VtFuHCZnl8eoKShCX9cfKLGFpAdWGOgO34P0n+P9KdD5Dg4O5reJTwXpPvrWeI=; Message-ID: <82bc736158e827e05d4b55da27c39d42e2062e96.1784809978.git.qemu_oss@crudebyte.com> In-Reply-To: References: From: Christian Schoenebeck Date: Thu, 23 Jul 2026 14:43:24 +0200 Subject: [PATCH v3 2/2] hw/9pfs/xen: drain in-flight PDUs before xen-9p disconnect To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, Greg Kurz , Stefano Stabellini , Anthony PERARD , "Edgar E. Iglesias" Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=5.189.157.229; envelope-from=82bc736158e827e05d4b55da27c39d42e2062e96@kylie.crudebyte.com; helo=kylie.crudebyte.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @crudebyte.com) X-ZM-MESSAGEID: 1784810891110158500 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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. Additionally, explicit calls of xen_9pfs_disconnect() in the error paths of xen_9pfs_pdu_vmarshal() and xen_9pfs_pdu_vunmarshal() must be deferred (via aio_bh_schedule_oneshot()), because xen_9pfs_pdu_v(un)marshal() are running within a coroutine context which makes them unsafe [1] for calling v9fs_reset() directly, as the latter e.g. has a loop like: while (!QLIST_EMPTY(&s->active_list)) { aio_poll(qemu_get_aio_context(), true); } which would a) never terminate (as the coroutine is on the active_list) and b) aio_poll() is marked as no_coroutine_fn. [1] https://lore.kernel.org/qemu-devel/3351181.5fSG56mABF@weasel/ And finally, add an idempotent guard to xen_9pfs_disconnect() for the v9fs_reset(s) and v9fs_device_unrealize_common(s) calls specifically [2], just to be sure. [2] https://lore.kernel.org/qemu-devel/alpine.DEB.2.22.394.2607221815520.52= 95@ubuntu-linux-20-04-desktop/ Fixes: b37eeb0201 ("xen/9pfs: introduce Xen 9pfs backend") Signed-off-by: Christian Schoenebeck Reviewed-by: Stefano Stabellini --- hw/9pfs/9p.c | 1 + hw/9pfs/xen-9p-backend.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 3119f01117..fc01791830 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -4530,6 +4530,7 @@ void v9fs_device_unrealize_common(V9fsState *s) qp_table_destroy(&s->qpp_table); qp_table_destroy(&s->qpf_table); g_free(s->ctx.fs_root); + s->transport =3D NULL; } =20 typedef struct VirtfsCoResetData { diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c index 24c90d97ec..a2f118d2ca 100644 --- a/hw/9pfs/xen-9p-backend.c +++ b/hw/9pfs/xen-9p-backend.c @@ -68,6 +68,11 @@ typedef struct Xen9pfsDev { =20 static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev); =20 +static void xen_9pfs_disconnect_bh(void *opaque) +{ + xen_9pfs_disconnect(opaque); +} + static void xen_9pfs_in_sg(Xen9pfsRing *ring, struct iovec *in_sg, int *num, @@ -150,7 +155,8 @@ static ssize_t xen_9pfs_pdu_vmarshal(V9fsPDU *pdu, "Failed to encode VirtFS reply type %d\n", pdu->id + 1); xen_be_set_state(&xen_9pfs->xendev, XenbusStateClosing); - xen_9pfs_disconnect(&xen_9pfs->xendev); + aio_bh_schedule_oneshot(qemu_get_aio_context(), + xen_9pfs_disconnect_bh, &xen_9pfs->xendev); } return ret; } @@ -173,7 +179,8 @@ static ssize_t xen_9pfs_pdu_vunmarshal(V9fsPDU *pdu, xen_pv_printf(&xen_9pfs->xendev, 0, "Failed to decode VirtFS request type %d\n", pdu->id= ); xen_be_set_state(&xen_9pfs->xendev, XenbusStateClosing); - xen_9pfs_disconnect(&xen_9pfs->xendev); + aio_bh_schedule_oneshot(qemu_get_aio_context(), + xen_9pfs_disconnect_bh, &xen_9pfs->xendev); } return ret; } @@ -368,10 +375,16 @@ static void xen_9pfs_evtchn_event(void *opaque) static void xen_9pfs_disconnect(struct XenLegacyDevice *xendev) { Xen9pfsDev *xen_9pdev =3D container_of(xendev, Xen9pfsDev, xendev); + V9fsState *s =3D &xen_9pdev->state; int i; =20 trace_xen_9pfs_disconnect(xendev->name); =20 + if (s->transport) { + v9fs_reset(s); + v9fs_device_unrealize_common(s); + } + for (i =3D 0; i < xen_9pdev->num_rings; i++) { if (xen_9pdev->rings[i].evtchndev !=3D NULL) { qemu_set_fd_handler(qemu_xen_evtchn_fd(xen_9pdev->rings[i].evt= chndev), --=20 2.47.3