mirror of
https://git.yoctoproject.org/poky
synced 2026-05-31 00:39:46 +00:00
qemu: Security Fix CVE-2016-3712
affects qemu < 2.6.0 (From OE-Core rev: 6f25d966c41df5315d253859d9ebf231963bf671) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
ffa3a07ac1
commit
98e7d8a9a0
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -21,6 +21,10 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \
|
|||||||
file://CVE-2016-2197.patch \
|
file://CVE-2016-2197.patch \
|
||||||
file://CVE-2016-2198.patch \
|
file://CVE-2016-2198.patch \
|
||||||
file://CVE-2016-3710.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_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2"
|
||||||
SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4"
|
SRC_URI[md5sum] = "186ee8194140a484a455f8e3c74589f4"
|
||||||
|
|||||||
Reference in New Issue
Block a user