[oe-commits] [openembedded-core] 15/20: qemu: Security Fix CVE-2016-3712

git at git.openembedded.org git at git.openembedded.org
Fri Sep 23 22:22:39 UTC 2016


rpurdie pushed a commit to branch jethro
in repository openembedded-core.

commit 6f25d966c41df5315d253859d9ebf231963bf671
Author: Armin Kuster <akuster at mvista.com>
AuthorDate: Mon Sep 19 18:12:42 2016 -0700

    qemu: Security Fix CVE-2016-3712
    
    affects qemu < 2.6.0
    
    Signed-off-by: Armin Kuster <akuster at mvista.com>
---
 .../qemu/qemu/CVE-2016-3712_p1.patch               |  73 ++++++++++++
 .../qemu/qemu/CVE-2016-3712_p2.patch               | 132 +++++++++++++++++++++
 .../qemu/qemu/CVE-2016-3712_p3.patch               |  34 ++++++
 .../qemu/qemu/CVE-2016-3712_p4.patch               |  80 +++++++++++++
 meta/recipes-devtools/qemu/qemu_2.4.0.bb           |   4 +
 5 files changed, 323 insertions(+)

diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch
new file mode 100644
index 0000000..07582ef
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch
@@ -0,0 +1,73 @@
+From 46aff2c7e91ef9f372ad38ba5e90c42b9b27ac75 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Tue, 26 Apr 2016 14:11:34 +0200
+Subject: [PATCH 1/4] vga: add vbe_enabled() helper
+
+Makes code a bit easier to read.
+
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+
+Upstream-Status: Backport
+CVE: CVE-2016-3712 patch1
+Signed-off-by: Armin Kuster <akuster at mvista.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 442fee9..cc1a682 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -140,6 +140,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;
+@@ -562,7 +567,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;
+     }
+@@ -1056,7 +1061,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;
+@@ -1381,7 +1386,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;
+@@ -1393,7 +1398,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.7.4
+
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch
new file mode 100644
index 0000000..11330d7
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch
@@ -0,0 +1,132 @@
+From 2f2f74e87c15e830f5a4dda7a166effcab5047ec Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Tue, 26 Apr 2016 15:24:18 +0200
+Subject: [PATCH 2/4] 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 at redhat.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+
+Upstream-Status: Backport
+CVE: CVE-2016-3712 patch2
+Signed-off-by: Armin Kuster <akuster at mvista.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 cc1a682..f1987e3 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -642,6 +642,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;
+@@ -728,52 +771,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.7.4
+
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch
new file mode 100644
index 0000000..3e6644d
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch
@@ -0,0 +1,34 @@
+From a6e5e5dd4bbc022acbd10ebcf415a6a57418d09e Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Tue, 26 Apr 2016 15:39:22 +0200
+Subject: [PATCH 3/4] 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 at redhat.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+
+Upstream-Status: Backport
+CVE: CVE-2016-3712 patch3
+Signed-off-by: Armin Kuster <akuster at mvista.com>
+
+---
+ hw/display/vga.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index f1987e3..10ac7df 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -761,6 +761,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.7.4
+
diff --git a/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch
new file mode 100644
index 0000000..96e980a
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch
@@ -0,0 +1,80 @@
+From 44b86aa32e4147c727fadd9a0f0bc503a5dedb72 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Tue, 26 Apr 2016 14:48:06 +0200
+Subject: [PATCH 4/4] 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 at alibaba-inc.com>
+Reported-by: P J P <ppandit at redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+
+Upstream-Status: Backport
+CVE: CVE-2016-3712 patch4 ( the fix)
+Signed-off-by: Armin Kuster <akuster at mvista.com>
+
+---
+ hw/display/vga.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/display/vga.c b/hw/display/vga.c
+index 10ac7df..679070e 100644
+--- a/hw/display/vga.c
++++ b/hw/display/vga.c
+@@ -140,6 +140,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;
+@@ -482,6 +484,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);
+         }
+@@ -513,6 +516,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:
+@@ -531,10 +535,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.7.4
+
diff --git a/meta/recipes-devtools/qemu/qemu_2.4.0.bb b/meta/recipes-devtools/qemu/qemu_2.4.0.bb
index f324242..85dd39e 100644
--- a/meta/recipes-devtools/qemu/qemu_2.4.0.bb
+++ b/meta/recipes-devtools/qemu/qemu_2.4.0.bb
@@ -21,6 +21,10 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \
             file://CVE-2016-2197.patch \
             file://CVE-2016-2198.patch \
             file://CVE-2016-3710.patch \
+            file://CVE-2016-3712_p1.patch \
+            file://CVE-2016-3712_p2.patch \
+            file://CVE-2016-3712_p3.patch \
+            file://CVE-2016-3712_p4.patch \
            "
 SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2"
 SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4"

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Openembedded-commits mailing list