From: Akihiko Odaki <[email protected]>

VIRTIO_GPU_CMD_SET_SCANOUT_BLOB supplies a guest-controlled uint32_t
stride, but some downstream consumers take it as int. They may interpret
a value greater than INT_MAX as negative and cause issues:

- pixman_image_create_bits() takes the stride as int, and Pixman may
  later access memory before the blob buffer.

- eglCreateImageKHR() also takes the stride as EGLint when importing the
  DMA-BUF, and Mesa rejects it.

Reject such strides before scanout.

The check in virtio_gpu_scanout_blob_to_fb() rejects unsupported blob
configurations early. The check added in virtio_gpu_do_set_scanout()
covers migration post_load.

Fixes: 32db3c63ae11 ("virtio-gpu: Add virtio_gpu_set_scanout_blob")
Signed-off-by: Akihiko Odaki <[email protected]>
Reviewed-by: Marc-André Lureau <[email protected]>
Message-ID: <[email protected]>
---
 hw/display/virtio-gpu.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 048b151872e..3090edf89a8 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -654,6 +654,14 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,
         return false;
     }
 
+    if (fb->stride > INT_MAX) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: stride is %" PRIu32
+                      ", larger than the supported maximum (%d)\n",
+                      __func__, fb->stride, INT_MAX);
+        *error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
+        return false;
+    }
+
     g->parent_obj.enable = 1;
 
     if (res->blob) {
@@ -769,6 +777,13 @@ bool virtio_gpu_scanout_blob_to_fb(struct 
virtio_gpu_framebuffer *fb,
         return false;
     }
 
+    if (fb->stride > INT_MAX) {
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: stride is %" PRIu32
+                      ", larger than the supported maximum (%d)\n",
+                      __func__, fb->stride, INT_MAX);
+        return false;
+    }
+
     fb->offset = ss->offsets[0] + ss->r.x * fb->bytes_pp + ss->r.y * 
fb->stride;
 
     fbend = fb->offset;

-- 
2.55.0


Reply via email to