]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/virtio: bound EDID block reads to the response buffer
authorBryam Vargas <hexlabsecurity@proton.me>
Sun, 21 Jun 2026 02:43:34 +0000 (21:43 -0500)
committerDmitry Osipenko <dmitry.osipenko@collabora.com>
Tue, 30 Jun 2026 13:04:27 +0000 (16:04 +0300)
virtio_get_edid_block() validates the read offset only against the
device-supplied resp->size field, never against the fixed-size resp->edid
array. The EDID block index is driven by the device-supplied extension
count, so a malicious virtio-gpu backend can advertise a large size
together with a high block count and read far past the array into adjacent
kernel memory, which is then surfaced in the parsed EDID (an out-of-bounds
read / info leak).

Also reject any read whose end exceeds the size of the edid array.
Conforming EDID responses stay within the array and are unaffected.

Fixes: b4b01b4995fb ("drm/virtio: add edid support")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260620-b4-disp-22bba7bf-v1-1-b95924cee742@proton.me
drivers/gpu/drm/virtio/virtgpu_vq.c

index 67865810a2e708fdd1a029d4cc18e77858059af2..c8b9475a7472e09abc61085231a2629f2fad593d 100644 (file)
@@ -897,7 +897,8 @@ static int virtio_get_edid_block(void *data, u8 *buf,
        struct virtio_gpu_resp_edid *resp = data;
        size_t start = block * EDID_LENGTH;
 
-       if (start + len > le32_to_cpu(resp->size))
+       if (start + len > le32_to_cpu(resp->size) ||
+           start + len > sizeof(resp->edid))
                return -EINVAL;
        memcpy(buf, resp->edid + start, len);
        return 0;