[PATCH] hw/display/virtio-gpu: validate blob iov size in create_blob

marcandre.lureau@redhat.com posted 1 patch 1 day, 2 hours ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260724035712.856636-1-marcandre.lureau@redhat.com
Maintainers: "Alex Bennée" <alex.bennee@linaro.org>, Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>, Dmitry Osipenko <dmitry.osipenko@collabora.com>, "Michael S. Tsirkin" <mst@redhat.com>
hw/display/virtio-gpu.c | 10 ++++++++++
1 file changed, 10 insertions(+)
[PATCH] hw/display/virtio-gpu: validate blob iov size in create_blob
Posted by marcandre.lureau@redhat.com 1 day, 2 hours ago
From: Marc-André Lureau <marcandre.lureau@redhat.com>

virtio_gpu_resource_create_blob() stores the guest-controlled blob_size
without checking it against the total size of the iov backing entries.
Since both values are independently guest-controlled, a malicious guest
can set blob_size much larger than the actual iov backing. Subsequent
SET_SCANOUT_BLOB checks bounds against the inflated blob_size, allowing
a pixman surface to be created over the undersized buffer. Any display
refresh then reads past the actual allocation, potentially crashing
QEMU or leaking host memory contents depending on the backing type.

Reject the resource early when the iov backing is smaller than the
declared blob_size.

Fixes: CVE-2026-66021
Fixes: e0933d91b1cd ("virtio-gpu: Add virtio_gpu_resource_create_blob")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3945
Reported-by: "sundayjiang(蒋浩天)" <sundayjiang@tencent.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 hw/display/virtio-gpu.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index eac039c3c366..cc6dbd116618 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -372,6 +372,16 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
         return;
     }
 
+    if (iov_size(res->iov, res->iov_cnt) < res->blob_size) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: backing storage smaller than blob size\n",
+                      __func__);
+        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        virtio_gpu_cleanup_mapping(g, res);
+        g_free(res);
+        return;
+    }
+
     virtio_gpu_init_udmabuf(res);
     QTAILQ_INSERT_HEAD(&g->reslist, res, next);
 }
-- 
2.55.0


Re: [PATCH] hw/display/virtio-gpu: validate blob iov size in create_blob
Posted by Akihiko Odaki 23 hours ago
On 2026/07/24 12:57, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> virtio_gpu_resource_create_blob() stores the guest-controlled blob_size
> without checking it against the total size of the iov backing entries.
> Since both values are independently guest-controlled, a malicious guest
> can set blob_size much larger than the actual iov backing. Subsequent
> SET_SCANOUT_BLOB checks bounds against the inflated blob_size, allowing
> a pixman surface to be created over the undersized buffer. Any display
> refresh then reads past the actual allocation, potentially crashing
> QEMU or leaking host memory contents depending on the backing type.
> 
> Reject the resource early when the iov backing is smaller than the
> declared blob_size.

The same invariant also needs to be enforced when backing is supplied
by VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING and when blob migration state
is loaded. Otherwise, newly attached backing or state received from an
older source can bypass this fix.

The check cannot be unconditional at resource creation, however. The
specification permits nr_entries == 0 so that backing can be attached
later for swap-in/swap-out. As written, this patch rejects that valid
request:

 > To facilitate drivers that support swap-in and swap-out, nr_entries
 > may be zero and VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING may be
 > subsequently used. VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING may be
 > used to unassign memory entries.

https://docs.oasis-open.org/virtio/virtio/v1.3/virtio-v1.3.html#x1-4120008

Regards,
Akihiko Odaki

> 
> Fixes: CVE-2026-66021
> Fixes: e0933d91b1cd ("virtio-gpu: Add virtio_gpu_resource_create_blob")
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3945
> Reported-by: "sundayjiang(蒋浩天)" <sundayjiang@tencent.com>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>   hw/display/virtio-gpu.c | 10 ++++++++++
>   1 file changed, 10 insertions(+)
> 
> diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> index eac039c3c366..cc6dbd116618 100644
> --- a/hw/display/virtio-gpu.c
> +++ b/hw/display/virtio-gpu.c
> @@ -372,6 +372,16 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
>           return;
>       }
>   
> +    if (iov_size(res->iov, res->iov_cnt) < res->blob_size) {
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "%s: backing storage smaller than blob size\n",
> +                      __func__);
> +        cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
> +        virtio_gpu_cleanup_mapping(g, res);
> +        g_free(res);
> +        return;
> +    }
> +
>       virtio_gpu_init_udmabuf(res);
>       QTAILQ_INSERT_HEAD(&g->reslist, res, next);
>   }