Commit 210701c82e for qemu.org

commit 210701c82e304622818989028e75192013cb81d8
Author: Jia Jia <physicalmtea@gmail.com>
Date:   Thu Jul 23 14:43:24 2026 +0200

    hw/9pfs/virtio: drain in-flight PDUs before virtio-9p unrealize

    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 <physicalmtea@gmail.com>
    [ Christian Schoenebeck: add commit log message. ]
    Link: https://lore.kernel.org/qemu-devel/bc503aefffd20b1806941b3ef708afbd92f0aef2.1784809978.git.qemu_oss@crudebyte.com
    Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 50dc93091d..576a794ea4 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 = VIRTIO_9P(dev);
     V9fsState *s = &v->state;

+    v9fs_reset(s); /* cancel all in-flight PDUs to prevent UAF */
     virtio_delete_queue(v->vq);
     virtio_cleanup(vdev);
     v9fs_device_unrealize_common(s);