diff options
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p1.patch | 73 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p2.patch | 132 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p3.patch | 34 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu/CVE-2016-3712_p4.patch | 80 | ||||
| -rw-r--r-- | meta/recipes-devtools/qemu/qemu_2.5.0.bb | 4 | 
5 files changed, 323 insertions, 0 deletions
| 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 0000000000..07582ef929 --- /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@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@redhat.com> +Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> + +Upstream-Status: Backport +CVE: CVE-2016-3712 patch1 +Signed-off-by: Armin Kuster <akuster@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 0000000000..11330d766d --- /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@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@redhat.com> +Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> + +Upstream-Status: Backport +CVE: CVE-2016-3712 patch2 +Signed-off-by: Armin Kuster <akuster@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 0000000000..3e6644d942 --- /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@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@redhat.com> +Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> + +Upstream-Status: Backport +CVE: CVE-2016-3712 patch3 +Signed-off-by: Armin Kuster <akuster@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 0000000000..96e980a58d --- /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@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@alibaba-inc.com> +Reported-by: P J P <ppandit@redhat.com> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> +Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> + +Upstream-Status: Backport +CVE: CVE-2016-3712 patch4 ( the fix) +Signed-off-by: Armin Kuster <akuster@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.5.0.bb b/meta/recipes-devtools/qemu/qemu_2.5.0.bb index 7651e9a5ae..a38edd59a4 100644 --- a/meta/recipes-devtools/qemu/qemu_2.5.0.bb +++ b/meta/recipes-devtools/qemu/qemu_2.5.0.bb @@ -17,6 +17,10 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \              file://rng_move_request_queue_cleanup_from_RngEgd_to_RngBackend.patch \              file://CVE-2016-2858.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] = "f469f2330bbe76e3e39db10e9ac4f8db" | 
