Hi
On Fri, Jul 24, 2026 at 12:01 PM Akihiko Odaki
<[email protected]> wrote:
>
> On 2026/07/24 13:01, [email protected] wrote:
> > From: Marc-André Lureau <[email protected]>
> >
> > virtio_gpu_scanout_blob_to_fb() computes the framebuffer offset from
> > guest-controlled offsets[0], r.x, r.y and stride using uint32_t
> > arithmetic. The sum can wrap around, so a small fb->offset passes the
> > fbend > blob_size check even though the real offset lies outside the
> > blob. The wrapped value is later used as data + fb->offset in
> > virtio_gpu_do_set_scanout(), letting the guest point the scanout at
> > host memory beyond the blob.
>
> fbend is computed from the same wrapped fb->offset that is later used
> for data + fb->offset. Since fbend is checked against blob_size, the
> wrapped pointer and scanout extent remain within the blob. Wraparound
> can select a different in-bounds region, but the described host
> out-of-bounds access does not follow.
Right, I'll drop the CVE and just make is a correctness patch instead.
>
> >
> > Compute the offset in uint64_t, reject values wider than UINT32_MAX
> > (the width of fb->offset), and only store into fb->offset once both
> > range checks pass.
> >
> > Fixes: CVE-2026-66019
> > Fixes: 32db3c63ae11 ("virtio-gpu: Add virtio_gpu_set_scanout_blob")
> > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3871
> > Reported-by: Cyber_black <[email protected]>
> > Signed-off-by: Marc-André Lureau <[email protected]>
> > ---
> > hw/display/virtio-gpu.c | 14 ++++++++------
> > 1 file changed, 8 insertions(+), 6 deletions(-)
> >
> > diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
> > index 36d2bd9edee6..d1e32840e223 100644
> > --- a/hw/display/virtio-gpu.c
> > +++ b/hw/display/virtio-gpu.c
> > @@ -784,7 +784,7 @@ bool virtio_gpu_scanout_blob_to_fb(struct
> > virtio_gpu_framebuffer *fb,
> > struct virtio_gpu_set_scanout_blob *ss,
> > uint64_t blob_size)
> > {
> > - uint64_t fbend;
> > + uint64_t fbend, offset;
> > uint32_t bytes_pp;
> >
> > fb->format = virtio_gpu_get_pixman_format(ss->format);
> > @@ -814,18 +814,20 @@ bool virtio_gpu_scanout_blob_to_fb(struct
> > virtio_gpu_framebuffer *fb,
> > return false;
> > }
> >
> > - fb->offset = ss->offsets[0] + ss->r.x * bytes_pp + ss->r.y *
> > fb->stride;
> > + offset = (uint64_t)ss->offsets[0] + (uint64_t)ss->r.x * bytes_pp +
> > + (uint64_t)ss->r.y * fb->stride;
> >
> > - fbend = fb->offset;
> > - fbend += (uint64_t) fb->stride * ss->r.height;
> > + fbend = offset + (uint64_t)fb->stride * ss->r.height;
> >
> > - if (fbend > blob_size) {
> > + if (offset > UINT32_MAX || fbend > blob_size) {
> > qemu_log_mask(LOG_GUEST_ERROR,
> > - "%s: fb end out of range\n",
> > + "%s: invalid fb bounds\n",
> > __func__);
> > return false;
> > }
> >
> > + fb->offset = offset;
> > +
> > return true;
> > }
> >
>
> This patch does not apply to master and appears to be based on:
>
> Based-on: <[email protected]>
> ("[PATCH] hw/display/virtio-gpu: Remove the bytes_pp field")
>
> The dependency is not declared. Please record the prerequisite.
>
> Regards,
> Akihiko Odaki
>