Commit 01df81b24c for qemu.org

commit 01df81b24c50fe70e816cce70956acd6ac632fc9
Author: Marc-André Lureau <marcandre.lureau@redhat.com>
Date:   Thu Sep 10 16:12:54 2026 -0400

    vhost-user-gpu: validate command buffer size in submit_3d

    virgl_cmd_submit_3d() passes the guest-controlled cs.size directly to
    g_malloc() without any bounds check. A malicious guest can set this
    field to an arbitrarily large value (up to 4GB), causing an OOM abort
    that crashes the vhost-user-gpu daemon.

    Validate cs.size against the actual descriptor payload size before
    allocating, rejecting values that exceed what the virtqueue entry
    can carry.

    Fixes: d52c454aadc ("contrib: add vhost-user-gpu")
    Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3776
    Reported-by: admin@fluentlogic.org
    Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
    Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    Message-ID: <20260713125431.107278-1-marcandre.lureau@redhat.com>
    Message-ID: <67f10fb88d3c75da3ba7fa5a37f7d6bcfcf3ce9e.1789071042.git.mst@redhat.com>

diff --git a/contrib/vhost-user-gpu/virgl.c b/contrib/vhost-user-gpu/virgl.c
index 5a5f9f14c8..0ef4b9d8c9 100644
--- a/contrib/vhost-user-gpu/virgl.c
+++ b/contrib/vhost-user-gpu/virgl.c
@@ -209,20 +209,24 @@ virgl_cmd_submit_3d(VuGpu *g,
                     struct virtio_gpu_ctrl_command *cmd)
 {
     struct virtio_gpu_cmd_submit cs;
+    size_t iov_len;
     void *buf;
     size_t s;

     VUGPU_FILL_CMD(cs);

-    if (cs.size > VIRTIO_GPU_MAX_CMD_SUBMIT_SIZE) {
-        g_critical("%s: command buffer too large (%u)",
-                   __func__, cs.size);
+    iov_len = iov_size(cmd->elem.out_sg, cmd->elem.out_num);
+    if (cs.size == 0 || iov_len < sizeof(cs) ||
+        cs.size > iov_len - sizeof(cs) ||
+        cs.size > VIRTIO_GPU_MAX_CMD_SUBMIT_SIZE) {
+        g_critical("%s: size out of range (%u/%zu)",
+                   __func__, cs.size, iov_len);
         cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
         return;
     }

     buf = g_try_malloc(cs.size);
-    if (!buf && cs.size) {
+    if (!buf) {
         cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
         return;
     }