Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.8005
CVE-2016-3712-qemuu-vga-add-sr_vbe-register-set...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2016-3712-qemuu-vga-add-sr_vbe-register-set.patch of Package xen.8005
Subject: vga: add sr_vbe register set From: Gerd Hoffmann kraxel@redhat.com Tue May 17 10:54:54 2016 +0200 Date: Mon May 23 14:28:25 2016 +0200: Git: 94ef4f337fb614f18b765a8e0e878a4c23cdedcd Commit "fd3c136 vga: make sure vga register setup for vbe stays intact (CVE-2016-3712)." causes a regression. The win7 installer is unhappy because it can't freely modify vga registers any more while in vbe mode. This patch introduces a new sr_vbe register set. The vbe_update_vgaregs will fill sr_vbe[] instead of sr[]. Normal vga register reads and writes go to sr[]. Any sr register read access happens through a new sr() helper function which will read from sr_vbe[] with vbe active and from sr[] otherwise. This way we can allow guests update sr[] registers as they want, without allowing them disrupt vbe video modes that way. Cc: qemu-stable@nongnu.org Reported-by: Thomas Lamprecht <thomas@lamprecht.org> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 1463475294-14119-1-git-send-email-kraxel@redhat.com Index: xen-4.4.4-testing/tools/qemu-xen-dir-remote/hw/display/vga.c =================================================================== --- xen-4.4.4-testing.orig/tools/qemu-xen-dir-remote/hw/display/vga.c +++ xen-4.4.4-testing/tools/qemu-xen-dir-remote/hw/display/vga.c @@ -173,6 +173,11 @@ static inline bool vbe_enabled(VGACommon return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; } +static inline uint8_t sr(VGACommonState *s, int idx) +{ + return vbe_enabled(s) ? s->sr_vbe[idx] : s->sr[idx]; +} + static void vga_update_memory_access(VGACommonState *s) { MemoryRegion *region, *old_region = s->chain4_alias; @@ -180,8 +185,8 @@ static void vga_update_memory_access(VGA s->chain4_alias = NULL; - if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) == - VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { + if ((sr(s, VGA_SEQ_PLANE_WRITE) & VGA_SR02_ALL_PLANES) == + VGA_SR02_ALL_PLANES && sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) { offset = 0; switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) { case 0: @@ -259,7 +264,7 @@ static void vga_precise_update_retrace_i ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8); vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf; - clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1; + clocking_mode = (sr(s, VGA_SEQ_CLOCK_MODE) >> 3) & 1; clock_sel = (s->msr >> 2) & 3; dots = (s->msr & 1) ? 8 : 9; @@ -515,7 +520,6 @@ void vga_ioport_write(void *opaque, uint printf("vga: write SR%x = 0x%02x\n", s->sr_index, val); #endif s->sr[s->sr_index] = val & sr_mask[s->sr_index]; - vbe_update_vgaregs(s); if (s->sr_index == VGA_SEQ_CLOCK_MODE) { s->update_retrace_info(s); } @@ -709,13 +713,13 @@ static void vbe_update_vgaregs(VGACommon if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { shift_control = 0; - s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ + s->sr_vbe[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ } else { shift_control = 2; /* set chain 4 mode */ - s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; + s->sr_vbe[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; /* activate all planes */ - s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; + s->sr_vbe[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; } s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) | (shift_control << 5); @@ -866,7 +870,7 @@ uint32_t vga_mem_readb(VGACommonState *s break; } - if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { + if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) { /* chain 4 mode : simplest access */ assert(addr < s->vram_size); ret = s->vram_ptr[addr]; @@ -934,11 +938,11 @@ void vga_mem_writeb(VGACommonState *s, h break; } - if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { + if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) { /* chain 4 mode : simplest access */ plane = addr & 3; mask = (1 << plane); - if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) { + if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) { assert(addr < s->vram_size); s->vram_ptr[addr] = val; #ifdef DEBUG_VGA_MEM @@ -951,7 +955,7 @@ void vga_mem_writeb(VGACommonState *s, h /* odd/even mode (aka text mode mapping) */ plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1); mask = (1 << plane); - if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) { + if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) { addr = ((addr & ~1) << 1) | plane; if (addr >= s->vram_size) { return; @@ -1026,7 +1030,7 @@ void vga_mem_writeb(VGACommonState *s, h do_write: /* mask data according to sr[2] */ - mask = s->sr[VGA_SEQ_PLANE_WRITE]; + mask = sr(s, VGA_SEQ_PLANE_WRITE); s->plane_updated |= mask; /* only used to detect font change */ write_mask = mask16[mask]; if (addr * sizeof(uint32_t) >= s->vram_size) { @@ -1317,10 +1321,10 @@ static void vga_get_text_resolution(VGAC /* total width & height */ cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1; cwidth = 8; - if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) { + if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) { cwidth = 9; } - if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) { + if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) { cwidth = 16; /* NOTE: no 18 pixel wide */ } width = (s->cr[VGA_CRTC_H_DISP] + 1); @@ -1376,7 +1380,7 @@ static void vga_draw_text(VGACommonState int64_t now = qemu_get_clock_ms(vm_clock); /* compute font data address (in plane 2) */ - v = s->sr[VGA_SEQ_CHARACTER_MAP]; + v = sr(s, VGA_SEQ_CHARACTER_MAP); offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; if (offset != s->font_offsets[0]) { s->font_offsets[0] = offset; @@ -1747,11 +1751,11 @@ static void vga_draw_graphic(VGACommonSt } if (shift_control == 0) { - if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { + if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { disp_width <<= 1; } } else if (shift_control == 1) { - if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { + if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { disp_width <<= 1; } } @@ -1792,7 +1796,7 @@ static void vga_draw_graphic(VGACommonSt if (shift_control == 0) { full_update |= update_palette16(s); - if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { + if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { v = VGA_DRAW_LINE4D2; } else { v = VGA_DRAW_LINE4; @@ -1800,7 +1804,7 @@ static void vga_draw_graphic(VGACommonSt bits = 4; } else if (shift_control == 1) { full_update |= update_palette16(s); - if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { + if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { v = VGA_DRAW_LINE2D2; } else { v = VGA_DRAW_LINE2; @@ -1848,7 +1852,7 @@ static void vga_draw_graphic(VGACommonSt #if 0 printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE], - s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]); + s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE)); #endif addr1 = (s->start_addr * 4); bwidth = (width * bits + 7) / 8; @@ -2007,6 +2011,7 @@ void vga_common_reset(VGACommonState *s) { s->sr_index = 0; memset(s->sr, '\0', sizeof(s->sr)); + memset(s->sr_vbe, '\0', sizeof(s->sr_vbe)); s->gr_index = 0; memset(s->gr, '\0', sizeof(s->gr)); s->ar_index = 0; @@ -2108,10 +2113,10 @@ static void vga_update_text(void *opaque /* total width & height */ cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1; cw = 8; - if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) { + if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) { cw = 9; } - if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) { + if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) { cw = 16; /* NOTE: no 18 pixel wide */ } width = (s->cr[VGA_CRTC_H_DISP] + 1); @@ -2277,6 +2282,7 @@ static int vga_common_post_load(void *op /* force refresh */ s->graphic_mode = -1; + vbe_update_vgaregs(s); return 0; } Index: xen-4.4.4-testing/tools/qemu-xen-dir-remote/hw/display/vga_int.h =================================================================== --- xen-4.4.4-testing.orig/tools/qemu-xen-dir-remote/hw/display/vga_int.h +++ xen-4.4.4-testing/tools/qemu-xen-dir-remote/hw/display/vga_int.h @@ -97,6 +97,7 @@ typedef struct VGACommonState { MemoryRegion *chain4_alias; uint8_t sr_index; uint8_t sr[256]; + uint8_t sr_vbe[256]; uint8_t gr_index; uint8_t gr[256]; uint8_t ar_index;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor