diff options
author | Gerd Hoffmann | 2017-08-28 14:29:06 +0200 |
---|---|---|
committer | Gerd Hoffmann | 2017-09-01 13:52:43 +0200 |
commit | 3d90c6254863693a6b13d918d2b8682e08bbc681 (patch) | |
tree | 41f305d2ad30ffad4ea463ca2c89f83e53eb2067 /hw/display/vga.c | |
parent | vga: fix display update region calculation (split screen) (diff) | |
download | qemu-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.c | 5 |
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, |