@samitouri / QOSamiQemu / commits / 9c724426f5

hw/display/virtio-gpu: reject strides exceeding INT_MAX

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 <odaki@rsg.ci.i.u-tokyo.ac.jp> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20260717-int-v1-1-8aa05e1791a0@rsg.ci.i.u-tokyo.ac.jp>

Akihiko Odaki committed Jul 17, 2026 at 16:41 UTC 9c724426f5192845b5975dc48165de06a3da50b2
1 file changed +15
hw/display/virtio-gpu.c
+15
@@ -654,6 +654,14 @@ static bool virtio_gpu_do_set_scanout(VirtIOGPU *g,
654 return false;
655 }
656
657 + if (fb->stride > INT_MAX) {
658 + qemu_log_mask(LOG_GUEST_ERROR, "%s: stride is %" PRIu32
659 + ", larger than the supported maximum (%d)\n",
660 + __func__, fb->stride, INT_MAX);
661 + *error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
662 + return false;
663 + }
664 +
665 g->parent_obj.enable = 1;
666
667 if (res->blob) {
@@ -769,6 +777,13 @@ bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb,
777 return false;
778 }
779
780 + if (fb->stride > INT_MAX) {
781 + qemu_log_mask(LOG_GUEST_ERROR, "%s: stride is %" PRIu32
782 + ", larger than the supported maximum (%d)\n",
783 + __func__, fb->stride, INT_MAX);
784 + return false;
785 + }
786 +
787 fb->offset = ss->offsets[0] + ss->r.x * fb->bytes_pp + ss->r.y * fb->stride;
788
789 fbend = fb->offset;