+++ /dev/null
-From 7fa5c2c5dc9f9bf878c1e8669eb9644d70a71e71 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 26 Apr 2016 15:24:18 +0200
-Subject: [PATCH] vga: factor out vga register setup
-
-When enabling vbe mode qemu will setup a bunch of vga registers to make
-sure the vga emulation operates in correct mode for a linear
-framebuffer. Move that code to a separate function so we can call it
-from other places too.
-
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/display/vga.c | 78 ++++++++++++++++++++++++++++++++------------------------
- 1 file changed, 44 insertions(+), 34 deletions(-)
-
-diff --git a/hw/display/vga.c b/hw/display/vga.c
-index 0c1c5b5..e12f5ac 100644
---- a/hw/display/vga.c
-+++ b/hw/display/vga.c
-@@ -644,6 +644,49 @@ static void vbe_fixup_regs(VGACommonState *s)
- s->vbe_start_addr = offset / 4;
- }
-
-+/* we initialize the VGA graphic mode */
-+static void vbe_update_vgaregs(VGACommonState *s)
-+{
-+ int h, shift_control;
-+
-+ if (!vbe_enabled(s)) {
-+ /* vbe is turned off -- nothing to do */
-+ return;
-+ }
-+
-+ /* graphic mode + memory map 1 */
-+ s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
-+ VGA_GR06_GRAPHICS_MODE;
-+ s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
-+ s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
-+ /* width */
-+ s->cr[VGA_CRTC_H_DISP] =
-+ (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
-+ /* height (only meaningful if < 1024) */
-+ h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
-+ s->cr[VGA_CRTC_V_DISP_END] = h;
-+ s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
-+ ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
-+ /* line compare to 1023 */
-+ s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
-+ s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
-+ s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
-+
-+ if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
-+ shift_control = 0;
-+ s->sr[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;
-+ /* activate all planes */
-+ s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
-+ }
-+ s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
-+ (shift_control << 5);
-+ s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
-+}
-+
- static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
- {
- VGACommonState *s = opaque;
-@@ -730,52 +773,19 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
- case VBE_DISPI_INDEX_ENABLE:
- if ((val & VBE_DISPI_ENABLED) &&
- !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
-- int h, shift_control;
-
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
- s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
- vbe_fixup_regs(s);
-+ vbe_update_vgaregs(s);
-
- /* clear the screen */
- if (!(val & VBE_DISPI_NOCLEARMEM)) {
- memset(s->vram_ptr, 0,
- s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
- }
--
-- /* we initialize the VGA graphic mode */
-- /* graphic mode + memory map 1 */
-- s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
-- VGA_GR06_GRAPHICS_MODE;
-- s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
-- s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
-- /* width */
-- s->cr[VGA_CRTC_H_DISP] =
-- (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
-- /* height (only meaningful if < 1024) */
-- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
-- s->cr[VGA_CRTC_V_DISP_END] = h;
-- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
-- ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
-- /* line compare to 1023 */
-- s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
-- s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
-- s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
--
-- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
-- shift_control = 0;
-- s->sr[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;
-- /* activate all planes */
-- s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
-- }
-- s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
-- (shift_control << 5);
-- s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
- } else {
- s->bank_offset = 0;
- }
---
-2.1.4
-
--- /dev/null
+From 3bf1817079bb0d80c0d8a86a7c7dd0bfe90eb82e Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 08:49:10 +0200
+Subject: [PATCH 1/5] vga: fix banked access bounds checking (CVE-2016-3710)
+
+vga allows banked access to video memory using the window at 0xa00000
+and it supports a different access modes with different address
+calculations.
+
+The VBE bochs extentions support banked access too, using the
+VBE_DISPI_INDEX_BANK register. The code tries to take the different
+address calculations into account and applies different limits to
+VBE_DISPI_INDEX_BANK depending on the current access mode.
+
+Which is probably effective in stopping misprogramming by accident.
+But from a security point of view completely useless as an attacker
+can easily change access modes after setting the bank register.
+
+Drop the bogus check, add range checks to vga_mem_{readb,writeb}
+instead.
+
+Fixes: CVE-2016-3710
+Reported-by: Qinghao Tang <luodalongde@gmail.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/vga.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 657e9f1..b9191ca 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -179,6 +179,7 @@ static void vga_update_memory_access(VGACommonState *s)
+ size = 0x8000;
+ break;
+ }
++ assert(offset + size <= s->vram_size);
+ base += isa_mem_base;
+ region = g_malloc(sizeof(*region));
+ memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
+@@ -716,11 +717,7 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
+ vbe_fixup_regs(s);
+ break;
+ case VBE_DISPI_INDEX_BANK:
+- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
+- val &= (s->vbe_bank_mask >> 2);
+- } else {
+- val &= s->vbe_bank_mask;
+- }
++ val &= s->vbe_bank_mask;
+ s->vbe_regs[s->vbe_index] = val;
+ s->bank_offset = (val << 16);
+ vga_update_memory_access(s);
+@@ -819,13 +816,21 @@ uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
+
+ if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
+ /* chain 4 mode : simplest access */
++ assert(addr < s->vram_size);
+ ret = s->vram_ptr[addr];
+ } else if (s->gr[VGA_GFX_MODE] & 0x10) {
+ /* odd/even mode (aka text mode mapping) */
+ plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
+- ret = s->vram_ptr[((addr & ~1) << 1) | plane];
++ addr = ((addr & ~1) << 1) | plane;
++ if (addr >= s->vram_size) {
++ return 0xff;
++ }
++ ret = s->vram_ptr[addr];
+ } else {
+ /* standard VGA latched access */
++ if (addr * sizeof(uint32_t) >= s->vram_size) {
++ return 0xff;
++ }
+ s->latch = ((uint32_t *)s->vram_ptr)[addr];
+
+ if (!(s->gr[VGA_GFX_MODE] & 0x08)) {
+@@ -882,6 +887,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
+ plane = addr & 3;
+ mask = (1 << plane);
+ if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
++ assert(addr < s->vram_size);
+ s->vram_ptr[addr] = val;
+ #ifdef DEBUG_VGA_MEM
+ printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
+@@ -895,6 +901,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
+ mask = (1 << plane);
+ if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
+ addr = ((addr & ~1) << 1) | plane;
++ if (addr >= s->vram_size) {
++ return;
++ }
+ s->vram_ptr[addr] = val;
+ #ifdef DEBUG_VGA_MEM
+ printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
+@@ -968,6 +977,9 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
+ mask = s->sr[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) {
++ return;
++ }
+ ((uint32_t *)s->vram_ptr)[addr] =
+ (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) |
+ (val & write_mask);
+--
+2.1.4
+
--- /dev/null
+From bfa0f151a564a83b5a26f3e917da98674bf3cf62 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 14:11:34 +0200
+Subject: [PATCH 2/5] vga: add vbe_enabled() helper
+
+Makes code a bit easier to read.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/vga.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index b9191ca..0c1c5b5 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -142,6 +142,11 @@ static uint32_t expand4[256];
+ static uint16_t expand2[256];
+ static uint8_t expand4to8[16];
+
++static inline bool vbe_enabled(VGACommonState *s)
++{
++ return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
++}
++
+ static void vga_update_memory_access(VGACommonState *s)
+ {
+ hwaddr base, offset, size;
+@@ -564,7 +569,7 @@ static void vbe_fixup_regs(VGACommonState *s)
+ uint16_t *r = s->vbe_regs;
+ uint32_t bits, linelength, maxy, offset;
+
+- if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
++ if (!vbe_enabled(s)) {
+ /* vbe is turned off -- nothing to do */
+ return;
+ }
+@@ -1058,7 +1063,7 @@ static void vga_get_offsets(VGACommonState *s,
+ {
+ uint32_t start_addr, line_offset, line_compare;
+
+- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
++ if (vbe_enabled(s)) {
+ line_offset = s->vbe_line_offset;
+ start_addr = s->vbe_start_addr;
+ line_compare = 65535;
+@@ -1383,7 +1388,7 @@ static int vga_get_bpp(VGACommonState *s)
+ {
+ int ret;
+
+- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
++ if (vbe_enabled(s)) {
+ ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
+ } else {
+ ret = 0;
+@@ -1395,7 +1400,7 @@ static void vga_get_resolution(VGACommonState *s, int *pwidth, int *pheight)
+ {
+ int width, height;
+
+- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
++ if (vbe_enabled(s)) {
+ width = s->vbe_regs[VBE_DISPI_INDEX_XRES];
+ height = s->vbe_regs[VBE_DISPI_INDEX_YRES];
+ } else {
+--
+2.1.4
+
+++ /dev/null
-From fd3c136b3e1482cd0ec7285d6bc2a3e6a62c38d7 Mon Sep 17 00:00:00 2001
-From: Gerd Hoffmann <kraxel@redhat.com>
-Date: Tue, 26 Apr 2016 14:48:06 +0200
-Subject: [PATCH] vga: make sure vga register setup for vbe stays intact
- (CVE-2016-3712).
-
-Call vbe_update_vgaregs() when the guest touches GFX, SEQ or CRT
-registers, to make sure the vga registers will always have the
-values needed by vbe mode. This makes sure the sanity checks
-applied by vbe_fixup_regs() are effective.
-
-Without this guests can muck with shift_control, can turn on planar
-vga modes or text mode emulation while VBE is active, making qemu
-take code paths meant for CGA compatibility, but with the very
-large display widths and heigts settable using VBE registers.
-
-Which is good for one or another buffer overflow. Not that
-critical as they typically read overflows happening somewhere
-in the display code. So guests can DoS by crashing qemu with a
-segfault, but it is probably not possible to break out of the VM.
-
-Fixes: CVE-2016-3712
-Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
-Reported-by: P J P <ppandit@redhat.com>
-Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
----
- hw/display/vga.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/hw/display/vga.c b/hw/display/vga.c
-index eeeb9c8..4a55ec6 100644
---- a/hw/display/vga.c
-+++ b/hw/display/vga.c
-@@ -142,6 +142,8 @@ static uint32_t expand4[256];
- static uint16_t expand2[256];
- static uint8_t expand4to8[16];
-
-+static void vbe_update_vgaregs(VGACommonState *s);
-+
- static void vga_update_memory_access(VGACommonState *s)
- {
- hwaddr base, offset, size;
-@@ -484,6 +486,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- 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);
- }
-@@ -515,6 +518,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
- #endif
- s->gr[s->gr_index] = val & gr_mask[s->gr_index];
-+ vbe_update_vgaregs(s);
- vga_update_memory_access(s);
- break;
- case VGA_CRT_IM:
-@@ -533,10 +537,12 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
- if (s->cr_index == VGA_CRTC_OVERFLOW) {
- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
- (val & 0x10);
-+ vbe_update_vgaregs(s);
- }
- return;
- }
- s->cr[s->cr_index] = val;
-+ vbe_update_vgaregs(s);
-
- switch(s->cr_index) {
- case VGA_CRTC_H_TOTAL:
---
-2.1.4
-
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
printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
--- /dev/null
+From 7fa5c2c5dc9f9bf878c1e8669eb9644d70a71e71 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 15:24:18 +0200
+Subject: [PATCH 3/5] vga: factor out vga register setup
+
+When enabling vbe mode qemu will setup a bunch of vga registers to make
+sure the vga emulation operates in correct mode for a linear
+framebuffer. Move that code to a separate function so we can call it
+from other places too.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/vga.c | 78 ++++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 44 insertions(+), 34 deletions(-)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 0c1c5b5..e12f5ac 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -644,6 +644,49 @@ static void vbe_fixup_regs(VGACommonState *s)
+ s->vbe_start_addr = offset / 4;
+ }
+
++/* we initialize the VGA graphic mode */
++static void vbe_update_vgaregs(VGACommonState *s)
++{
++ int h, shift_control;
++
++ if (!vbe_enabled(s)) {
++ /* vbe is turned off -- nothing to do */
++ return;
++ }
++
++ /* graphic mode + memory map 1 */
++ s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
++ VGA_GR06_GRAPHICS_MODE;
++ s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
++ s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
++ /* width */
++ s->cr[VGA_CRTC_H_DISP] =
++ (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
++ /* height (only meaningful if < 1024) */
++ h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
++ s->cr[VGA_CRTC_V_DISP_END] = h;
++ s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
++ ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
++ /* line compare to 1023 */
++ s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
++ s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
++ s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
++
++ if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
++ shift_control = 0;
++ s->sr[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;
++ /* activate all planes */
++ s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
++ }
++ s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
++ (shift_control << 5);
++ s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
++}
++
+ static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
+ {
+ VGACommonState *s = opaque;
+@@ -730,52 +773,19 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
+ case VBE_DISPI_INDEX_ENABLE:
+ if ((val & VBE_DISPI_ENABLED) &&
+ !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
+- int h, shift_control;
+
+ s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0;
+ s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
+ s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
+ s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
+ vbe_fixup_regs(s);
++ vbe_update_vgaregs(s);
+
+ /* clear the screen */
+ if (!(val & VBE_DISPI_NOCLEARMEM)) {
+ memset(s->vram_ptr, 0,
+ s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
+ }
+-
+- /* we initialize the VGA graphic mode */
+- /* graphic mode + memory map 1 */
+- s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 |
+- VGA_GR06_GRAPHICS_MODE;
+- s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */
+- s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3;
+- /* width */
+- s->cr[VGA_CRTC_H_DISP] =
+- (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1;
+- /* height (only meaningful if < 1024) */
+- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1;
+- s->cr[VGA_CRTC_V_DISP_END] = h;
+- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) |
+- ((h >> 7) & 0x02) | ((h >> 3) & 0x40);
+- /* line compare to 1023 */
+- s->cr[VGA_CRTC_LINE_COMPARE] = 0xff;
+- s->cr[VGA_CRTC_OVERFLOW] |= 0x10;
+- s->cr[VGA_CRTC_MAX_SCAN] |= 0x40;
+-
+- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
+- shift_control = 0;
+- s->sr[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;
+- /* activate all planes */
+- s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
+- }
+- s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
+- (shift_control << 5);
+- s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */
+ } else {
+ s->bank_offset = 0;
+ }
+--
+2.1.4
+
--- /dev/null
+From 2068192dcccd8a80dddfcc8df6164cf9c26e0fc4 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 15:39:22 +0200
+Subject: [PATCH 4/5] vga: update vga register setup on vbe changes
+
+Call the new vbe_update_vgaregs() function on vbe configuration
+changes, to make sure vga registers are up-to-date.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/vga.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index e12f5ac..eeeb9c8 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -763,6 +763,7 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
+ case VBE_DISPI_INDEX_Y_OFFSET:
+ s->vbe_regs[s->vbe_index] = val;
+ vbe_fixup_regs(s);
++ vbe_update_vgaregs(s);
+ break;
+ case VBE_DISPI_INDEX_BANK:
+ val &= s->vbe_bank_mask;
+--
+2.1.4
+
--- /dev/null
+From fd3c136b3e1482cd0ec7285d6bc2a3e6a62c38d7 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 26 Apr 2016 14:48:06 +0200
+Subject: [PATCH 5/5] vga: make sure vga register setup for vbe stays intact
+ (CVE-2016-3712).
+
+Call vbe_update_vgaregs() when the guest touches GFX, SEQ or CRT
+registers, to make sure the vga registers will always have the
+values needed by vbe mode. This makes sure the sanity checks
+applied by vbe_fixup_regs() are effective.
+
+Without this guests can muck with shift_control, can turn on planar
+vga modes or text mode emulation while VBE is active, making qemu
+take code paths meant for CGA compatibility, but with the very
+large display widths and heigts settable using VBE registers.
+
+Which is good for one or another buffer overflow. Not that
+critical as they typically read overflows happening somewhere
+in the display code. So guests can DoS by crashing qemu with a
+segfault, but it is probably not possible to break out of the VM.
+
+Fixes: CVE-2016-3712
+Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
+Reported-by: P J P <ppandit@redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/vga.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index eeeb9c8..4a55ec6 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -142,6 +142,8 @@ static uint32_t expand4[256];
+ static uint16_t expand2[256];
+ static uint8_t expand4to8[16];
+
++static void vbe_update_vgaregs(VGACommonState *s);
++
+ static inline bool vbe_enabled(VGACommonState *s)
+ {
+ return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
+@@ -484,6 +486,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+ 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);
+ }
+@@ -515,6 +518,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+ printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
+ #endif
+ s->gr[s->gr_index] = val & gr_mask[s->gr_index];
++ vbe_update_vgaregs(s);
+ vga_update_memory_access(s);
+ break;
+ case VGA_CRT_IM:
+@@ -533,10 +537,12 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+ if (s->cr_index == VGA_CRTC_OVERFLOW) {
+ s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) |
+ (val & 0x10);
++ vbe_update_vgaregs(s);
+ }
+ return;
+ }
+ s->cr[s->cr_index] = val;
++ vbe_update_vgaregs(s);
+
+ switch(s->cr_index) {
+ case VGA_CRTC_H_TOTAL:
+--
+2.1.4
+
0003-rng-move-request-queue-cleanup-from-RngEgd-to-RngBac.patch
0005-virtio-rng-ask-for-more-data-if-queue-is-not-fully-d.patch
CVE-2016-2858-0004-rng-add-request-queue-support-to-rng-random.patch
-#0001-vga-factor-out-vga-register-setup.patch
-#0002-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
-#0003-vga-add-sr_vbe-register-set.patch
+0001-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch
+0002-vga-add-vbe_enabled-helper.patch
+0003-vga-factor-out-vga-register-setup.patch
+0004-vga-update-vga-register-setup-on-vbe-changes.patch
+0005-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
+0003-vga-add-sr_vbe-register-set.patch
0001-scsi-esp-make-cmdbuf-big-enough-for-maximum-CDB-size.patch
0002-scsi-esp-fix-migration.patch
0004-vmsvga-move-fifo-sanity-checks-to-vmsvga_fifo_length.patch