summaryrefslogtreecommitdiffstats
path: root/hw/display/vga.c
diff options
context:
space:
mode:
authorGerd Hoffmann2017-08-28 14:29:06 +0200
committerGerd Hoffmann2017-09-01 13:52:43 +0200
commit3d90c6254863693a6b13d918d2b8682e08bbc681 (patch)
tree41f305d2ad30ffad4ea463ca2c89f83e53eb2067 /hw/display/vga.c
parentvga: fix display update region calculation (split screen) (diff)
downloadqemu-3d90c6254863693a6b13d918d2b8682e08bbc681.tar.gz
qemu-3d90c6254863693a6b13d918d2b8682e08bbc681.tar.xz
qemu-3d90c6254863693a6b13d918d2b8682e08bbc681.zip
vga: stop passing pointers to vga_draw_line* functions
Instead pass around the address (aka offset into vga memory). Add vga_read_* helper functions which apply vbe_size_mask to the address, to make sure the address stays within the valid range, similar to the cirrus blitter fixes (commits ffaf857778 and 026aeffcb4). Impact: DoS for privileged guest users. qemu crashes with a segfault, when hitting the guard page after vga memory allocation, while reading vga memory for display updates. Fixes: CVE-2017-13672 Cc: P J P <ppandit@redhat.com> Reported-by: David Buchanan <d@vidbuchanan.co.uk> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 20170828122906.18993-1-kraxel@redhat.com
Diffstat (limited to 'hw/display/vga.c')
-rw-r--r--hw/display/vga.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/hw/display/vga.c b/hw/display/vga.c
index ad7a46563c..6fc8c8708a 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1005,7 +1005,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
}
typedef void vga_draw_line_func(VGACommonState *s1, uint8_t *d,
- const uint8_t *s, int width);
+ uint32_t srcaddr, int width);
#include "vga-helpers.h"
@@ -1666,7 +1666,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (y_start < 0)
y_start = y;
if (!(is_buffer_shared(surface))) {
- vga_draw_line(s, d, s->vram_ptr + addr, width);
+ vga_draw_line(s, d, addr, width);
if (s->cursor_draw_line)
s->cursor_draw_line(s, d, y);
}
@@ -2170,6 +2170,7 @@ void vga_common_init(VGACommonState *s, Object *obj, bool global_vmstate)
if (!s->vbe_size) {
s->vbe_size = s->vram_size;
}
+ s->vbe_size_mask = s->vbe_size - 1;
s->is_vbe_vmstate = 1;
memory_region_init_ram_nomigrate(&s->vram, obj, "vga.vram", s->vram_size,