On 2026/08/25 19:20, Marc-André Lureau wrote:
Hi,
While working on CVE-2026-66020 (which had a few revision on list), I
kept finding several places where virtio-gpu scanout and dmabuf
ownership was unclear.
The CVE comes from using a blob after RESOURCE_DETACH_BACKING has
unmapped its memory. Following that path also found stale dmabuf
references, duplicated scanout bookkeeping, and inconsistent cleanup
between display backends.
This series makes each virtio_gpu_scanout own its current dmabuf and
uses resource_id to track which resource it displays. It also makes
QemuDmaBuf own its file descriptors and moves GTK fence state out of the
dmabuf.
Those changes touch a lot of area and I have done basic testing with the
various backends. I would not recommend backporting them to stable:
there is a high risk of introducing regressions. Yet, I don't know how
to address all the problems uncovered by CVE-2026-66020 in a simple
patch series. Help welcome!
If you mean "all the problems", my coding agent tells there are some
problems remaining:
1. Vhost-user still has duplicate, incomplete DMA-BUF ownership.
VhostUserGPU retains its separate g->dmabuf[]. The contrib backend
disables a scanout using ordinary VHOST_USER_GPU_SCANOUT with zero
dimensions, but the QEMU frontend handles that by only calling
qemu_console_set_surface().
Although that changes con->scanout.kind, it neither releases
g->dmabuf[id] nor invokes the frontend GL-disable callback. GTK/SDL can
therefore retain their private scanout mode and redraw the old buffer;
the wrapper and owned fd remain until another DMA-BUF message. Reset and
finalize also never free this array.
Separately, contrib’s virgl RESOURCE_UNREF destroys the renderer
resource without disabling scanouts using it. The in-process virgl
backend fixes precisely this case, but contrib does not.
2. GTK DMA-BUF texture release lacks the required GL context.
GTK’s release callback directly calls egl_dmabuf_release_texture(),
which calls glDeleteTextures() and then unconditionally forgets the
texture ID. Neither it nor the core release dispatcher establishes the
owning context.
This is reachable after another GTK console’s surface update leaves
EGL_NO_CONTEXT current. Deletion is then not guaranteed, yet the ID is
lost, leaking the GL import and backing. With another unshared context
current, a coincident texture name could be deleted from the wrong
context. SDL has the same missing-context pattern.
3. Rutabaga resource destruction remains incomplete.
virtio_gpu_rutabaga_resource_unref() calls Rutabaga unref and frees the
QEMU resource, but does not clean res->iov/res->addrs or remove a mapped
blob’s host-visible MemoryRegion. Only explicit RESOURCE_UNMAP_BLOB
removes that region.
Consequently, MAP_BLOB → RESOURCE_UNREF or reset can leave a
MemoryRegion pointing at storage destroyed by Rutabaga, as well as
pinned DMA mappings. This is adjacent to, rather than the original
scanout-detach CVE, but it is another unresolved blob-ownership problem.
...so there is still some work to be done.
But when it comes to backporting, I think we can instead do focused
backporting to avoid extra trouble. Concretely, the patches you tagged
with "Fixes: CVE-2026-66020" can be backported, namely:
- "[PATCH 10/18] virtio-gpu: disable blob scanouts on mapping cleanup" and
- "[PATCH 18/18] virtio-gpu: fix use-after-free on blob cursor after detach"
The latter is interchangeable with "[PATCH v2 4/5]
hw/display/virtio-gpu: Check cursor data presence", which I posted
(sorry but I forgot the presence of your cursor fix.)
These patches fix use-after-free that can have unpredictable
consequences and is potentially vulnerable.
Other patches fix stale DMA-BUF references and potential resource leaks.
While they are real bugs and can lead to problems like display glitches
and high memory usage, these risks are minor and their security
implication is probably negligible.
Regards,
Akihiko Odaki
thanks
Signed-off-by: Marc-André Lureau <[email protected]>
---
Marc-André Lureau (18):
ui/gtk: move GL fence tracking from QemuDmaBuf to VirtualGfxConsole
ui/dbus: disable scanout iff dmabuf is current
virtio-gpu: store the scanout DMABUF in virtio_gpu_scanout
ui/console: disable GL scanout when dmabuf is the active one
ui/sdl2: clear guest_fb.dmabuf on release
ui/dmabuf: own and close fds on free
virtio-gpu: release the dmabuf when a scanout is disabled
contrib/vhost-user-gpu: drop scanout_bitmask bookkeeping
virtio-gpu-rutabaga: fix scanout handling
virtio-gpu: disable blob scanouts on mapping cleanup
virtio-gpu: drop scanout_bitmask bookkeeping
virtio-gpu: release dmabuf when switching to a surface
virtio-gpu/virgl: release dmabuf when a texture replaces a scanout
virtio-gpu: consolidate disabling scanout
virtio-gpu: minor refactoring
virtio-gpu/virgl: disable scanouts on resource unref
virtio-gpu: initialize dmabuf_fd to -1
virtio-gpu: fix use-after-free on blob cursor after detach
contrib/vhost-user-gpu/vhost-user-gpu.c | 28 +++-------
hw/display/vhost-user-gpu.c | 1 -
hw/display/virtio-gpu-rutabaga.c | 26 +++++++---
hw/display/virtio-gpu-udmabuf-stubs.c | 2 +-
hw/display/virtio-gpu-udmabuf.c | 90 +++++++++++----------------------
hw/display/virtio-gpu-virgl.c | 75 +++++++++++++++------------
hw/display/virtio-gpu.c | 82 +++++++++++++++++++-----------
hw/vfio/display.c | 1 -
include/hw/virtio/virtio-gpu.h | 18 ++-----
include/ui/dmabuf.h | 5 --
include/ui/egl-helpers.h | 4 +-
include/ui/gtk.h | 8 +--
ui/console.c | 3 ++
ui/dbus-listener.c | 69 +++++++++++++++++--------
ui/dmabuf.c | 51 +++----------------
ui/egl-helpers.c | 15 +++---
ui/gtk-egl.c | 30 ++++++-----
ui/gtk-gl-area.c | 12 ++---
ui/gtk.c | 31 +++++++++---
ui/sdl2-gl.c | 5 ++
20 files changed, 277 insertions(+), 279 deletions(-)
---
base-commit: 82706188517bd102ed25f1931c4cb041ecf3ef50
change-id: 20260825-virtio-gpu-cleanup-dfb2ba185936
Best regards,
--
Marc-André Lureau <[email protected]>