[PATCH] hw/display/vhost-user-gpu: validate message payload sizes

marcandre.lureau@redhat.com posted 1 patch 1 week, 5 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260713125130.101787-1-marcandre.lureau@redhat.com
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Stefano Garzarella <sgarzare@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>
hw/display/vhost-user-gpu.c | 38 +++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
[PATCH] hw/display/vhost-user-gpu: validate message payload sizes
Posted by marcandre.lureau@redhat.com 1 week, 5 days ago
From: Marc-André Lureau <marcandre.lureau@redhat.com>

A malicious or buggy vhost-user-gpu backend can send messages with
undersized payloads, leading to out-of-bounds reads when the handler
accesses struct fields beyond the allocated buffer. However,
vhost-user-gpu is considered trusted by QEMU by design (it has access to
shared memory etc).

Add a centralized minimum payload size check in vhost_user_gpu_chr_read()
that rejects messages before dispatch, and a per-pixel bounds check in
the VHOST_USER_GPU_UPDATE handler to ensure the variable-length data
covers the declared width x height.

Fixes: 267f66465 ("hw/display: add vhost-user-vga & gpu-pci")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3866
Reported-by: Feifan Qian <bea1e@proton.me>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/display/vhost-user-gpu.c | 38 +++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 57360898ca0..cd684d63639 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -119,6 +119,31 @@ static VhostUserGpuMsg m __attribute__ ((unused));
 
 static void vhost_user_gpu_update_blocked(VhostUserGPU *g, bool blocked);
 
+static size_t
+vhost_user_gpu_min_payload_size(VhostUserGpuRequest request)
+{
+    switch (request) {
+    case VHOST_USER_GPU_CURSOR_POS:
+    case VHOST_USER_GPU_CURSOR_POS_HIDE:
+        return sizeof(VhostUserGpuCursorPos);
+    case VHOST_USER_GPU_CURSOR_UPDATE:
+        return sizeof(VhostUserGpuCursorUpdate);
+    case VHOST_USER_GPU_GET_EDID:
+        return sizeof(VhostUserGpuEdidRequest);
+    case VHOST_USER_GPU_SCANOUT:
+        return sizeof(VhostUserGpuScanout);
+    case VHOST_USER_GPU_DMABUF_SCANOUT:
+        return sizeof(VhostUserGpuDMABUFScanout);
+    case VHOST_USER_GPU_DMABUF_SCANOUT2:
+        return sizeof(VhostUserGpuDMABUFScanout2);
+    case VHOST_USER_GPU_DMABUF_UPDATE:
+    case VHOST_USER_GPU_UPDATE:
+        return sizeof(VhostUserGpuUpdate);
+    default:
+        return 0;
+    }
+}
+
 static void
 vhost_user_gpu_handle_cursor(VhostUserGPU *g, VhostUserGpuMsg *msg)
 {
@@ -322,6 +347,14 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg)
         if (m->scanout_id >= g->parent_obj.conf.max_outputs) {
             break;
         }
+
+        if ((uint64_t)m->width * m->height >
+            (msg->size - sizeof(VhostUserGpuUpdate)) / sizeof(uint32_t)) {
+            error_report("vhost-user-gpu: update payload too small"
+                         " for %ux%u", m->width, m->height);
+            break;
+        }
+
         s = &g->parent_obj.scanout[m->scanout_id];
         con = s->con;
         pixman_image_t *image =
@@ -396,6 +429,11 @@ vhost_user_gpu_chr_read(void *opaque)
     msg->flags = flags;
     msg->size = size;
 
+    if (size < vhost_user_gpu_min_payload_size(request)) {
+        error_report("vhost-user-gpu: message %d payload too small", request);
+        goto end;
+    }
+
     if (request == VHOST_USER_GPU_CURSOR_UPDATE ||
         request == VHOST_USER_GPU_CURSOR_POS ||
         request == VHOST_USER_GPU_CURSOR_POS_HIDE) {
-- 
2.55.0


Re: [PATCH] hw/display/vhost-user-gpu: validate message payload sizes
Posted by Thomas Huth 5 days, 12 hours ago
On 13/07/2026 14.51, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> A malicious or buggy vhost-user-gpu backend can send messages with
> undersized payloads, leading to out-of-bounds reads when the handler
> accesses struct fields beyond the allocated buffer. However,
> vhost-user-gpu is considered trusted by QEMU by design (it has access to
> shared memory etc).
> 
> Add a centralized minimum payload size check in vhost_user_gpu_chr_read()
> that rejects messages before dispatch, and a per-pixel bounds check in
> the VHOST_USER_GPU_UPDATE handler to ensure the variable-length data
> covers the declared width x height.
> 
> Fixes: 267f66465 ("hw/display: add vhost-user-vga & gpu-pci")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3866
> Reported-by: Feifan Qian <bea1e@proton.me>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   hw/display/vhost-user-gpu.c | 38 +++++++++++++++++++++++++++++++++++++
>   1 file changed, 38 insertions(+)

Reviewed-by: Thomas Huth <thuth@redhat.com>