Fix spice audio playback sample rate (bz #1129961)
Fix virtio-blk migration incompatibility caused by CVE backport (bz #1115604) CVE-2014-3615 Fix crash when guest sets high resolution (bz #1139121, bz #1139115)
This commit is contained in:
parent
f182f276c2
commit
d9094d4c0b
@ -0,0 +1,81 @@
|
|||||||
|
From 4e31c89ca161180c62c66ec457fcd3d57efc0d86 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jeremy White <jwhite@codeweavers.com>
|
||||||
|
Date: Thu, 2 Jan 2014 09:25:56 -0600
|
||||||
|
Subject: [PATCH] Add the ability to vary Spice playback and record rates, to
|
||||||
|
facilitate Opus support.
|
||||||
|
|
||||||
|
Signed-off-by: Jeremy White <jwhite@codeweavers.com>
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
(cherry picked from commit 795ca114d353e02752a29f64902215bb30c58c21)
|
||||||
|
---
|
||||||
|
audio/spiceaudio.c | 27 +++++++++++++++++++++++++--
|
||||||
|
1 file changed, 25 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
|
||||||
|
index bc24557..a717361 100644
|
||||||
|
--- a/audio/spiceaudio.c
|
||||||
|
+++ b/audio/spiceaudio.c
|
||||||
|
@@ -25,8 +25,17 @@
|
||||||
|
#include "audio.h"
|
||||||
|
#include "audio_int.h"
|
||||||
|
|
||||||
|
-#define LINE_IN_SAMPLES 1024
|
||||||
|
-#define LINE_OUT_SAMPLES 1024
|
||||||
|
+#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
|
||||||
|
+#define LINE_OUT_SAMPLES (480 * 4)
|
||||||
|
+#else
|
||||||
|
+#define LINE_OUT_SAMPLES (256 * 4)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
|
||||||
|
+#define LINE_IN_SAMPLES (480 * 4)
|
||||||
|
+#else
|
||||||
|
+#define LINE_IN_SAMPLES (256 * 4)
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
typedef struct SpiceRateCtl {
|
||||||
|
int64_t start_ticks;
|
||||||
|
@@ -111,7 +120,11 @@ static int line_out_init (HWVoiceOut *hw, struct audsettings *as)
|
||||||
|
SpiceVoiceOut *out = container_of (hw, SpiceVoiceOut, hw);
|
||||||
|
struct audsettings settings;
|
||||||
|
|
||||||
|
+#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
|
||||||
|
+ settings.freq = spice_server_get_best_playback_rate(NULL);
|
||||||
|
+#else
|
||||||
|
settings.freq = SPICE_INTERFACE_PLAYBACK_FREQ;
|
||||||
|
+#endif
|
||||||
|
settings.nchannels = SPICE_INTERFACE_PLAYBACK_CHAN;
|
||||||
|
settings.fmt = AUD_FMT_S16;
|
||||||
|
settings.endianness = AUDIO_HOST_ENDIANNESS;
|
||||||
|
@@ -122,6 +135,9 @@ static int line_out_init (HWVoiceOut *hw, struct audsettings *as)
|
||||||
|
|
||||||
|
out->sin.base.sif = &playback_sif.base;
|
||||||
|
qemu_spice_add_interface (&out->sin.base);
|
||||||
|
+#if SPICE_INTERFACE_PLAYBACK_MAJOR > 1 || SPICE_INTERFACE_PLAYBACK_MINOR >= 3
|
||||||
|
+ spice_server_set_playback_rate(&out->sin, settings.freq);
|
||||||
|
+#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -232,7 +248,11 @@ static int line_in_init (HWVoiceIn *hw, struct audsettings *as)
|
||||||
|
SpiceVoiceIn *in = container_of (hw, SpiceVoiceIn, hw);
|
||||||
|
struct audsettings settings;
|
||||||
|
|
||||||
|
+#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
|
||||||
|
+ settings.freq = spice_server_get_best_record_rate(NULL);
|
||||||
|
+#else
|
||||||
|
settings.freq = SPICE_INTERFACE_RECORD_FREQ;
|
||||||
|
+#endif
|
||||||
|
settings.nchannels = SPICE_INTERFACE_RECORD_CHAN;
|
||||||
|
settings.fmt = AUD_FMT_S16;
|
||||||
|
settings.endianness = AUDIO_HOST_ENDIANNESS;
|
||||||
|
@@ -243,6 +263,9 @@ static int line_in_init (HWVoiceIn *hw, struct audsettings *as)
|
||||||
|
|
||||||
|
in->sin.base.sif = &record_sif.base;
|
||||||
|
qemu_spice_add_interface (&in->sin.base);
|
||||||
|
+#if SPICE_INTERFACE_RECORD_MAJOR > 2 || SPICE_INTERFACE_RECORD_MINOR >= 3
|
||||||
|
+ spice_server_set_record_rate(&in->sin, settings.freq);
|
||||||
|
+#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
54
0408-Allow-mismatched-virtio-config-len.patch
Normal file
54
0408-Allow-mismatched-virtio-config-len.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From 99159a10ae89685a03751d4b576a3602e0c17554 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
|
||||||
|
Date: Fri, 27 Jun 2014 20:02:48 +0100
|
||||||
|
Subject: [PATCH] Allow mismatched virtio config-len
|
||||||
|
|
||||||
|
Commit 'virtio: validate config_len on load' restricted config_len
|
||||||
|
loaded from the wire to match the config_len that the device had.
|
||||||
|
|
||||||
|
Unfortunately, there are cases where this isn't true, the one
|
||||||
|
we found it on was the wce addition in virtio-blk.
|
||||||
|
|
||||||
|
Allow mismatched config-lengths:
|
||||||
|
*) If the version on the wire is shorter then fine
|
||||||
|
*) If the version on the wire is longer, load what we have space
|
||||||
|
for and skip the rest.
|
||||||
|
|
||||||
|
(This is mst@redhat.com's rework of what I originally posted)
|
||||||
|
|
||||||
|
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
||||||
|
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||||
|
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||||
|
(cherry picked from commit 2f5732e9648fcddc8759a8fd25c0b41a38352be6)
|
||||||
|
---
|
||||||
|
hw/virtio/virtio.c | 16 +++++++++++-----
|
||||||
|
1 file changed, 11 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
||||||
|
index 151fae9..df7e048 100644
|
||||||
|
--- a/hw/virtio/virtio.c
|
||||||
|
+++ b/hw/virtio/virtio.c
|
||||||
|
@@ -923,12 +923,18 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
config_len = qemu_get_be32(f);
|
||||||
|
- if (config_len != vdev->config_len) {
|
||||||
|
- error_report("Unexpected config length 0x%x. Expected 0x%zx",
|
||||||
|
- config_len, vdev->config_len);
|
||||||
|
- return -1;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * There are cases where the incoming config can be bigger or smaller
|
||||||
|
+ * than what we have; so load what we have space for, and skip
|
||||||
|
+ * any excess that's in the stream.
|
||||||
|
+ */
|
||||||
|
+ qemu_get_buffer(f, vdev->config, MIN(config_len, vdev->config_len));
|
||||||
|
+
|
||||||
|
+ while (config_len > vdev->config_len) {
|
||||||
|
+ qemu_get_byte(f);
|
||||||
|
+ config_len--;
|
||||||
|
}
|
||||||
|
- qemu_get_buffer(f, vdev->config, vdev->config_len);
|
||||||
|
|
||||||
|
num = qemu_get_be32(f);
|
||||||
|
|
@ -0,0 +1,80 @@
|
|||||||
|
From e3e3ec3a981c0e1d2cb1e53a41c7dfec48ddcfdb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Tue, 26 Aug 2014 14:16:30 +0200
|
||||||
|
Subject: [PATCH] vbe: make bochs dispi interface return the correct memory
|
||||||
|
size with qxl
|
||||||
|
|
||||||
|
VgaState->vram_size is the size of the pci bar. In case of qxl not the
|
||||||
|
whole pci bar can be used as vga framebuffer. Add a new variable
|
||||||
|
vbe_size to handle that case. By default (if unset) it equals
|
||||||
|
vram_size, but qxl can set vbe_size to something else.
|
||||||
|
|
||||||
|
This makes sure VBE_DISPI_INDEX_VIDEO_MEMORY_64K returns correct results
|
||||||
|
and sanity checks are done with the correct size too.
|
||||||
|
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
(cherry picked from commit 54a85d462447c1cb8a1638578a7fd086350b4d2d)
|
||||||
|
---
|
||||||
|
hw/display/qxl.c | 1 +
|
||||||
|
hw/display/vga.c | 7 +++++--
|
||||||
|
hw/display/vga_int.h | 1 +
|
||||||
|
3 files changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
|
||||||
|
index 7ef3eff..31035f5 100644
|
||||||
|
--- a/hw/display/qxl.c
|
||||||
|
+++ b/hw/display/qxl.c
|
||||||
|
@@ -2067,6 +2067,7 @@ static int qxl_init_primary(PCIDevice *dev)
|
||||||
|
|
||||||
|
qxl->id = 0;
|
||||||
|
qxl_init_ramsize(qxl);
|
||||||
|
+ vga->vbe_size = qxl->vgamem_size;
|
||||||
|
vga->vram_size_mb = qxl->vga.vram_size >> 20;
|
||||||
|
vga_common_init(vga, OBJECT(dev));
|
||||||
|
vga_init(vga, OBJECT(dev),
|
||||||
|
diff --git a/hw/display/vga.c b/hw/display/vga.c
|
||||||
|
index 06f44a8..2f13e43 100644
|
||||||
|
--- a/hw/display/vga.c
|
||||||
|
+++ b/hw/display/vga.c
|
||||||
|
@@ -614,7 +614,7 @@ uint32_t vbe_ioport_read_data(void *opaque, uint32_t addr)
|
||||||
|
val = s->vbe_regs[s->vbe_index];
|
||||||
|
}
|
||||||
|
} else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) {
|
||||||
|
- val = s->vram_size / (64 * 1024);
|
||||||
|
+ val = s->vbe_size / (64 * 1024);
|
||||||
|
} else {
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
@@ -753,7 +753,7 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
line_offset = w >> 1;
|
||||||
|
else
|
||||||
|
line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
||||||
|
- h = s->vram_size / line_offset;
|
||||||
|
+ h = s->vbe_size / line_offset;
|
||||||
|
/* XXX: support weird bochs semantics ? */
|
||||||
|
if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
|
||||||
|
return;
|
||||||
|
@@ -2291,6 +2291,9 @@ void vga_common_init(VGACommonState *s, Object *obj)
|
||||||
|
s->vram_size <<= 1;
|
||||||
|
}
|
||||||
|
s->vram_size_mb = s->vram_size >> 20;
|
||||||
|
+ if (!s->vbe_size) {
|
||||||
|
+ s->vbe_size = s->vram_size;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
s->is_vbe_vmstate = 1;
|
||||||
|
memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size);
|
||||||
|
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
|
||||||
|
index e641890..999567c 100644
|
||||||
|
--- a/hw/display/vga_int.h
|
||||||
|
+++ b/hw/display/vga_int.h
|
||||||
|
@@ -93,6 +93,7 @@ typedef struct VGACommonState {
|
||||||
|
MemoryRegion vram_vbe;
|
||||||
|
uint32_t vram_size;
|
||||||
|
uint32_t vram_size_mb; /* property */
|
||||||
|
+ uint32_t vbe_size;
|
||||||
|
uint32_t latch;
|
||||||
|
MemoryRegion *chain4_alias;
|
||||||
|
uint8_t sr_index;
|
234
0410-vbe-rework-sanity-checks.patch
Normal file
234
0410-vbe-rework-sanity-checks.patch
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
From a2f8a1cc86f620317010f4ce12331235bde47a1c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Tue, 26 Aug 2014 15:35:23 +0200
|
||||||
|
Subject: [PATCH] vbe: rework sanity checks
|
||||||
|
|
||||||
|
Plug a bunch of holes in the bochs dispi interface parameter checking.
|
||||||
|
Add a function doing verification on all registers. Call that
|
||||||
|
unconditionally on every register write. That way we should catch
|
||||||
|
everything, even changing one register affecting the valid range of
|
||||||
|
another register.
|
||||||
|
|
||||||
|
Some of the holes have been added by commit
|
||||||
|
e9c6149f6ae6873f14a12eea554925b6aa4c4dec. Before that commit the
|
||||||
|
maximum possible framebuffer (VBE_DISPI_MAX_XRES * VBE_DISPI_MAX_YRES *
|
||||||
|
32 bpp) has been smaller than the qemu vga memory (8MB) and the checking
|
||||||
|
for VBE_DISPI_MAX_XRES + VBE_DISPI_MAX_YRES + VBE_DISPI_MAX_BPP was ok.
|
||||||
|
|
||||||
|
Some of the holes have been there forever, such as
|
||||||
|
VBE_DISPI_INDEX_X_OFFSET and VBE_DISPI_INDEX_Y_OFFSET register writes
|
||||||
|
lacking any verification.
|
||||||
|
|
||||||
|
Security impact:
|
||||||
|
|
||||||
|
(1) Guest can make the ui (gtk/vnc/...) use memory rages outside the vga
|
||||||
|
frame buffer as source -> host memory leak. Memory isn't leaked to
|
||||||
|
the guest but to the vnc client though.
|
||||||
|
|
||||||
|
(2) Qemu will segfault in case the memory range happens to include
|
||||||
|
unmapped areas -> Guest can DoS itself.
|
||||||
|
|
||||||
|
The guest can not modify host memory, so I don't think this can be used
|
||||||
|
by the guest to escape.
|
||||||
|
|
||||||
|
CVE-2014-3615
|
||||||
|
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Cc: secalert@redhat.com
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
(cherry picked from commit c1b886c45dc70f247300f549dce9833f3fa2def5)
|
||||||
|
---
|
||||||
|
hw/display/vga.c | 154 ++++++++++++++++++++++++++++++++++---------------------
|
||||||
|
1 file changed, 95 insertions(+), 59 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/display/vga.c b/hw/display/vga.c
|
||||||
|
index 2f13e43..cdb2e6b 100644
|
||||||
|
--- a/hw/display/vga.c
|
||||||
|
+++ b/hw/display/vga.c
|
||||||
|
@@ -580,6 +580,93 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Sanity check vbe register writes.
|
||||||
|
+ *
|
||||||
|
+ * As we don't have a way to signal errors to the guest in the bochs
|
||||||
|
+ * dispi interface we'll go adjust the registers to the closest valid
|
||||||
|
+ * value.
|
||||||
|
+ */
|
||||||
|
+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)) {
|
||||||
|
+ /* vbe is turned off -- nothing to do */
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check depth */
|
||||||
|
+ switch (r[VBE_DISPI_INDEX_BPP]) {
|
||||||
|
+ case 4:
|
||||||
|
+ case 8:
|
||||||
|
+ case 16:
|
||||||
|
+ case 24:
|
||||||
|
+ case 32:
|
||||||
|
+ bits = r[VBE_DISPI_INDEX_BPP];
|
||||||
|
+ break;
|
||||||
|
+ case 15:
|
||||||
|
+ bits = 16;
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ bits = r[VBE_DISPI_INDEX_BPP] = 8;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check width */
|
||||||
|
+ r[VBE_DISPI_INDEX_XRES] &= ~7u;
|
||||||
|
+ if (r[VBE_DISPI_INDEX_XRES] == 0) {
|
||||||
|
+ r[VBE_DISPI_INDEX_XRES] = 8;
|
||||||
|
+ }
|
||||||
|
+ if (r[VBE_DISPI_INDEX_XRES] > VBE_DISPI_MAX_XRES) {
|
||||||
|
+ r[VBE_DISPI_INDEX_XRES] = VBE_DISPI_MAX_XRES;
|
||||||
|
+ }
|
||||||
|
+ r[VBE_DISPI_INDEX_VIRT_WIDTH] &= ~7u;
|
||||||
|
+ if (r[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) {
|
||||||
|
+ r[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES;
|
||||||
|
+ }
|
||||||
|
+ if (r[VBE_DISPI_INDEX_VIRT_WIDTH] < r[VBE_DISPI_INDEX_XRES]) {
|
||||||
|
+ r[VBE_DISPI_INDEX_VIRT_WIDTH] = r[VBE_DISPI_INDEX_XRES];
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check height */
|
||||||
|
+ linelength = r[VBE_DISPI_INDEX_VIRT_WIDTH] * bits / 8;
|
||||||
|
+ maxy = s->vbe_size / linelength;
|
||||||
|
+ if (r[VBE_DISPI_INDEX_YRES] == 0) {
|
||||||
|
+ r[VBE_DISPI_INDEX_YRES] = 1;
|
||||||
|
+ }
|
||||||
|
+ if (r[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) {
|
||||||
|
+ r[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES;
|
||||||
|
+ }
|
||||||
|
+ if (r[VBE_DISPI_INDEX_YRES] > maxy) {
|
||||||
|
+ r[VBE_DISPI_INDEX_YRES] = maxy;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* check offset */
|
||||||
|
+ if (r[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) {
|
||||||
|
+ r[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES;
|
||||||
|
+ }
|
||||||
|
+ if (r[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) {
|
||||||
|
+ r[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES;
|
||||||
|
+ }
|
||||||
|
+ offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
|
||||||
|
+ offset += r[VBE_DISPI_INDEX_Y_OFFSET] * linelength;
|
||||||
|
+ if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
|
||||||
|
+ r[VBE_DISPI_INDEX_Y_OFFSET] = 0;
|
||||||
|
+ offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8;
|
||||||
|
+ if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) {
|
||||||
|
+ r[VBE_DISPI_INDEX_X_OFFSET] = 0;
|
||||||
|
+ offset = 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* update vga state */
|
||||||
|
+ r[VBE_DISPI_INDEX_VIRT_HEIGHT] = maxy;
|
||||||
|
+ s->vbe_line_offset = linelength;
|
||||||
|
+ s->vbe_start_addr = offset / 4;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr)
|
||||||
|
{
|
||||||
|
VGACommonState *s = opaque;
|
||||||
|
@@ -649,22 +736,13 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VBE_DISPI_INDEX_XRES:
|
||||||
|
- if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) {
|
||||||
|
- s->vbe_regs[s->vbe_index] = val;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
case VBE_DISPI_INDEX_YRES:
|
||||||
|
- if (val <= VBE_DISPI_MAX_YRES) {
|
||||||
|
- s->vbe_regs[s->vbe_index] = val;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
case VBE_DISPI_INDEX_BPP:
|
||||||
|
- if (val == 0)
|
||||||
|
- val = 8;
|
||||||
|
- if (val == 4 || val == 8 || val == 15 ||
|
||||||
|
- val == 16 || val == 24 || val == 32) {
|
||||||
|
- s->vbe_regs[s->vbe_index] = val;
|
||||||
|
- }
|
||||||
|
+ case VBE_DISPI_INDEX_VIRT_WIDTH:
|
||||||
|
+ case VBE_DISPI_INDEX_X_OFFSET:
|
||||||
|
+ case VBE_DISPI_INDEX_Y_OFFSET:
|
||||||
|
+ s->vbe_regs[s->vbe_index] = val;
|
||||||
|
+ vbe_fixup_regs(s);
|
||||||
|
break;
|
||||||
|
case VBE_DISPI_INDEX_BANK:
|
||||||
|
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
|
||||||
|
@@ -681,19 +759,11 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
|
||||||
|
int h, shift_control;
|
||||||
|
|
||||||
|
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
|
||||||
|
- s->vbe_regs[VBE_DISPI_INDEX_XRES];
|
||||||
|
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
|
||||||
|
- s->vbe_regs[VBE_DISPI_INDEX_YRES];
|
||||||
|
+ 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;
|
||||||
|
-
|
||||||
|
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
|
||||||
|
- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
|
||||||
|
- else
|
||||||
|
- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
|
||||||
|
- ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
||||||
|
- s->vbe_start_addr = 0;
|
||||||
|
+ s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED;
|
||||||
|
+ vbe_fixup_regs(s);
|
||||||
|
|
||||||
|
/* clear the screen (should be done in BIOS) */
|
||||||
|
if (!(val & VBE_DISPI_NOCLEARMEM)) {
|
||||||
|
@@ -742,40 +812,6 @@ void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
|
||||||
|
s->vbe_regs[s->vbe_index] = val;
|
||||||
|
vga_update_memory_access(s);
|
||||||
|
break;
|
||||||
|
- case VBE_DISPI_INDEX_VIRT_WIDTH:
|
||||||
|
- {
|
||||||
|
- int w, h, line_offset;
|
||||||
|
-
|
||||||
|
- if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES])
|
||||||
|
- return;
|
||||||
|
- w = val;
|
||||||
|
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
|
||||||
|
- line_offset = w >> 1;
|
||||||
|
- else
|
||||||
|
- line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
||||||
|
- h = s->vbe_size / line_offset;
|
||||||
|
- /* XXX: support weird bochs semantics ? */
|
||||||
|
- if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES])
|
||||||
|
- return;
|
||||||
|
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w;
|
||||||
|
- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h;
|
||||||
|
- s->vbe_line_offset = line_offset;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
- case VBE_DISPI_INDEX_X_OFFSET:
|
||||||
|
- case VBE_DISPI_INDEX_Y_OFFSET:
|
||||||
|
- {
|
||||||
|
- int x;
|
||||||
|
- s->vbe_regs[s->vbe_index] = val;
|
||||||
|
- s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET];
|
||||||
|
- x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET];
|
||||||
|
- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
|
||||||
|
- s->vbe_start_addr += x >> 1;
|
||||||
|
- else
|
||||||
|
- s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
|
||||||
|
- s->vbe_start_addr >>= 2;
|
||||||
|
- }
|
||||||
|
- break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
80
0411-spice-make-sure-we-don-t-overflow-ssd-buf.patch
Normal file
80
0411-spice-make-sure-we-don-t-overflow-ssd-buf.patch
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
From a954dcaa5006710dffec91cb140fa1b5eabced7e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Date: Wed, 3 Sep 2014 15:50:08 +0200
|
||||||
|
Subject: [PATCH] spice: make sure we don't overflow ssd->buf
|
||||||
|
|
||||||
|
Related spice-only bug. We have a fixed 16 MB buffer here, being
|
||||||
|
presented to the spice-server as qxl video memory in case spice is
|
||||||
|
used with a non-qxl card. It's also used with qxl in vga mode.
|
||||||
|
|
||||||
|
When using display resolutions requiring more than 16 MB of memory we
|
||||||
|
are going to overflow that buffer. In theory the guest can write,
|
||||||
|
indirectly via spice-server. The spice-server clears the memory after
|
||||||
|
setting a new video mode though, triggering a segfault in the overflow
|
||||||
|
case, so qemu crashes before the guest has a chance to do something
|
||||||
|
evil.
|
||||||
|
|
||||||
|
Fix that by switching to dynamic allocation for the buffer.
|
||||||
|
|
||||||
|
CVE-2014-3615
|
||||||
|
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
Cc: secalert@redhat.com
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
(cherry picked from commit ab9509cceabef28071e41bdfa073083859c949a7)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
ui/spice-display.c
|
||||||
|
---
|
||||||
|
ui/spice-display.c | 20 +++++++++++++++-----
|
||||||
|
1 file changed, 15 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ui/spice-display.c b/ui/spice-display.c
|
||||||
|
index 82d8b9f..b130fe8 100644
|
||||||
|
--- a/ui/spice-display.c
|
||||||
|
+++ b/ui/spice-display.c
|
||||||
|
@@ -308,11 +308,23 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
|
||||||
|
void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd)
|
||||||
|
{
|
||||||
|
QXLDevSurfaceCreate surface;
|
||||||
|
+ uint64_t surface_size;
|
||||||
|
|
||||||
|
memset(&surface, 0, sizeof(surface));
|
||||||
|
|
||||||
|
- dprint(1, "%s: %dx%d\n", __FUNCTION__,
|
||||||
|
- surface_width(ssd->ds), surface_height(ssd->ds));
|
||||||
|
+ surface_size = (uint64_t) surface_width(ssd->ds) *
|
||||||
|
+ surface_height(ssd->ds) * 4;
|
||||||
|
+ assert(surface_size > 0);
|
||||||
|
+ assert(surface_size < INT_MAX);
|
||||||
|
+ if (ssd->bufsize < surface_size) {
|
||||||
|
+ ssd->bufsize = surface_size;
|
||||||
|
+ g_free(ssd->buf);
|
||||||
|
+ ssd->buf = g_malloc(ssd->bufsize);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ dprint(1, "%s/%d: %ux%u (size %" PRIu64 "/%d)\n", __func__, ssd->qxl.id,
|
||||||
|
+ surface_width(ssd->ds), surface_height(ssd->ds),
|
||||||
|
+ surface_size, ssd->bufsize);
|
||||||
|
|
||||||
|
surface.format = SPICE_SURFACE_FMT_32_xRGB;
|
||||||
|
surface.width = surface_width(ssd->ds);
|
||||||
|
@@ -343,8 +355,6 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd)
|
||||||
|
if (ssd->num_surfaces == 0) {
|
||||||
|
ssd->num_surfaces = 1024;
|
||||||
|
}
|
||||||
|
- ssd->bufsize = (16 * 1024 * 1024);
|
||||||
|
- ssd->buf = g_malloc(ssd->bufsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* display listener callbacks */
|
||||||
|
@@ -462,7 +472,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info)
|
||||||
|
info->num_memslots = NUM_MEMSLOTS;
|
||||||
|
info->num_memslots_groups = NUM_MEMSLOTS_GROUPS;
|
||||||
|
info->internal_groupslot_id = 0;
|
||||||
|
- info->qxl_ram_size = ssd->bufsize;
|
||||||
|
+ info->qxl_ram_size = 16 * 1024 * 1024;
|
||||||
|
info->n_surfaces = ssd->num_surfaces;
|
||||||
|
}
|
||||||
|
|
29
qemu.spec
29
qemu.spec
@ -139,7 +139,7 @@
|
|||||||
Summary: QEMU is a FAST! processor emulator
|
Summary: QEMU is a FAST! processor emulator
|
||||||
Name: qemu
|
Name: qemu
|
||||||
Version: 1.6.2
|
Version: 1.6.2
|
||||||
Release: 7%{?dist}
|
Release: 8%{?dist}
|
||||||
Epoch: 2
|
Epoch: 2
|
||||||
License: GPLv2+ and LGPLv2+ and BSD
|
License: GPLv2+ and LGPLv2+ and BSD
|
||||||
Group: Development/Tools
|
Group: Development/Tools
|
||||||
@ -347,6 +347,16 @@ Patch0405: 0405-qcow1-Stricter-backing-file-length-check.patch
|
|||||||
# CVE-2014-3461: Issues in USB post load checks (bz #1097260, bz
|
# CVE-2014-3461: Issues in USB post load checks (bz #1097260, bz
|
||||||
# #1096821)
|
# #1096821)
|
||||||
Patch0406: 0406-usb-fix-up-post-load-checks.patch
|
Patch0406: 0406-usb-fix-up-post-load-checks.patch
|
||||||
|
# Fix spice audio playback sample rate (bz #1129961)
|
||||||
|
Patch0407: 0407-Add-the-ability-to-vary-Spice-playback-and-record-ra.patch
|
||||||
|
# Fix virtio-blk migration incompatibility caused by CVE backport (bz
|
||||||
|
# #1115604)
|
||||||
|
Patch0408: 0408-Allow-mismatched-virtio-config-len.patch
|
||||||
|
# CVE-2014-3615 Fix crash when guest sets high resolution (bz #1139121,
|
||||||
|
# bz #1139115)
|
||||||
|
Patch0409: 0409-vbe-make-bochs-dispi-interface-return-the-correct-me.patch
|
||||||
|
Patch0410: 0410-vbe-rework-sanity-checks.patch
|
||||||
|
Patch0411: 0411-spice-make-sure-we-don-t-overflow-ssd-buf.patch
|
||||||
|
|
||||||
BuildRequires: SDL-devel
|
BuildRequires: SDL-devel
|
||||||
BuildRequires: zlib-devel
|
BuildRequires: zlib-devel
|
||||||
@ -1026,6 +1036,16 @@ CAC emulation development files.
|
|||||||
# CVE-2014-3461: Issues in USB post load checks (bz #1097260, bz
|
# CVE-2014-3461: Issues in USB post load checks (bz #1097260, bz
|
||||||
# #1096821)
|
# #1096821)
|
||||||
%patch0406 -p1
|
%patch0406 -p1
|
||||||
|
# Fix spice audio playback sample rate (bz #1129961)
|
||||||
|
%patch0407 -p1
|
||||||
|
# Fix virtio-blk migration incompatibility caused by CVE backport (bz
|
||||||
|
# #1115604)
|
||||||
|
%patch0408 -p1
|
||||||
|
# CVE-2014-3615 Fix crash when guest sets high resolution (bz #1139121,
|
||||||
|
# bz #1139115)
|
||||||
|
%patch0409 -p1
|
||||||
|
%patch0410 -p1
|
||||||
|
%patch0411 -p1
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
@ -1733,6 +1753,13 @@ getent passwd qemu >/dev/null || \
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Sep 08 2014 Cole Robinson <crobinso@redhat.com> - 2:1.6.2-8
|
||||||
|
- Fix spice audio playback sample rate (bz #1129961)
|
||||||
|
- Fix virtio-blk migration incompatibility caused by CVE backport (bz
|
||||||
|
#1115604)
|
||||||
|
- CVE-2014-3615 Fix crash when guest sets high resolution (bz #1139121, bz
|
||||||
|
#1139115)
|
||||||
|
|
||||||
* Thu Jul 17 2014 Rex Dieter <rdieter@fedoraproject.org> - 2:1.6.2-7
|
* Thu Jul 17 2014 Rex Dieter <rdieter@fedoraproject.org> - 2:1.6.2-7
|
||||||
- rebuild (for pulseaudio, bug #1117683)
|
- rebuild (for pulseaudio, bug #1117683)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user