9ae3a8
From 5c99bd7a9de1f1a64d948776482ae7103091fac2 Mon Sep 17 00:00:00 2001
9ae3a8
From: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Date: Fri, 26 Jan 2018 07:30:05 +0100
9ae3a8
Subject: [PATCH 2/4] vga: check the validation of memory addr when draw text
9ae3a8
9ae3a8
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Message-id: <20180126073005.15344-2-kraxel@redhat.com>
9ae3a8
Patchwork-id: 78710
9ae3a8
O-Subject: [RHEL-7.5 qemu-kvm PATCH 1/1] vga: check the validation of memory addr when draw text
9ae3a8
Bugzilla: 1534691
9ae3a8
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9ae3a8
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
9ae3a8
From: linzhecheng <linzhecheng@huawei.com>
9ae3a8
9ae3a8
Start a vm with qemu-kvm -enable-kvm -vnc :66 -smp 1 -m 1024 -hda
9ae3a8
redhat_5.11.qcow2  -device pcnet -vga cirrus,
9ae3a8
then use VNC client to connect to VM, and excute the code below in guest
9ae3a8
OS will lead to qemu crash:
9ae3a8
9ae3a8
int main()
9ae3a8
 {
9ae3a8
    iopl(3);
9ae3a8
    srand(time(NULL));
9ae3a8
    int a,b;
9ae3a8
    while(1){
9ae3a8
	a = rand()%0x100;
9ae3a8
	b = 0x3c0 + (rand()%0x20);
9ae3a8
        outb(a,b);
9ae3a8
    }
9ae3a8
    return 0;
9ae3a8
}
9ae3a8
9ae3a8
The above code is writing the registers of VGA randomly.
9ae3a8
We can write VGA CRT controller registers index 0x0C or 0x0D
9ae3a8
(which is the start address register) to modify the
9ae3a8
the display memory address of the upper left pixel
9ae3a8
or character of the screen. The address may be out of the
9ae3a8
range of vga ram. So we should check the validation of memory address
9ae3a8
when reading or writing it to avoid segfault.
9ae3a8
9ae3a8
Signed-off-by: linzhecheng <linzhecheng@huawei.com>
9ae3a8
Message-id: 20180111132724.13744-1-linzhecheng@huawei.com
9ae3a8
Fixes: CVE-2018-5683
9ae3a8
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
(cherry picked from commit 191f59dc17396bb5a8da50f8c59b6e0a430711a4)
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/display/vga.c | 3 +++
9ae3a8
 1 file changed, 3 insertions(+)
9ae3a8
9ae3a8
diff --git a/hw/display/vga.c b/hw/display/vga.c
9ae3a8
index c40744f..017e951 100644
9ae3a8
--- a/hw/display/vga.c
9ae3a8
+++ b/hw/display/vga.c
9ae3a8
@@ -1328,6 +1328,9 @@ static void vga_draw_text(VGACommonState *s, int full_update)
9ae3a8
         cx_min = width;
9ae3a8
         cx_max = -1;
9ae3a8
         for(cx = 0; cx < width; cx++) {
9ae3a8
+            if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) {
9ae3a8
+                break;
9ae3a8
+            }
9ae3a8
             ch_attr = *(uint16_t *)src;
9ae3a8
             if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) {
9ae3a8
                 if (cx < cx_min)
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8