QEMU is a FAST! processor emulator
CentOS Sources
2016-08-11 6078803a0db76660aef491907f795bb23ad33357
import qemu-kvm-1.5.3-105.el7_2.7
3 files added
1 files modified
395 ■■■■■ changed files
SOURCES/kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch 60 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-vga-add-sr_vbe-register-set.patch 252 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch 57 ●●●●● patch | view | raw | blame | history
SPECS/qemu-kvm.spec 26 ●●●●● patch | view | raw | blame | history
SOURCES/kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch
New file
@@ -0,0 +1,60 @@
From f5596dffdad4014342239c7d3ec85e637969d2de Mon Sep 17 00:00:00 2001
From: Fam Zheng <famz@redhat.com>
Date: Fri, 29 Jul 2016 07:54:22 +0200
Subject: [PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
RH-Author: Fam Zheng <famz@redhat.com>
Message-id: <1469778862-32607-1-git-send-email-famz@redhat.com>
Patchwork-id: 71515
O-Subject: [RHEL-7.2.z qemu-kvm PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
Bugzilla: 1358996
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Laurent Vivier <lvivier@redhat.com>
From: Peter Lieven <pl@kamp.de>
at least in the path via virtio-blk the maximum size is not
restricted.
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1464080368-29584-1-git-send-email-pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a6b3167fa0e825aebb5a7cd8b437b6d41584a196)
 Conflicts:
    block/iscsi.c
Upstream uses qemu_aio_unref, downstream uses qemu_aio_release.
Also, context in conflict because downstream doesn't have 4bb17ab51
(iscsi: Emulate commands in iscsi_aio_ioctl as iscsi_ioctl).
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 block/iscsi.c | 7 +++++++
 1 file changed, 7 insertions(+)
diff --git a/block/iscsi.c b/block/iscsi.c
index 92dc1dd..d472ee8 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -698,6 +698,13 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
     acb->buf         = NULL;
     acb->ioh         = buf;
+    if (acb->ioh->cmd_len > SCSI_CDB_MAX_SIZE) {
+        error_report("iSCSI: ioctl error CDB exceeds max size (%d > %d)",
+                     acb->ioh->cmd_len, SCSI_CDB_MAX_SIZE);
+        qemu_aio_release(acb);
+        return NULL;
+    }
+
     acb->task = malloc(sizeof(struct scsi_task));
     if (acb->task == NULL) {
         error_report("iSCSI: Failed to allocate task for scsi command. %s",
--
1.8.3.1
SOURCES/kvm-vga-add-sr_vbe-register-set.patch
New file
@@ -0,0 +1,252 @@
From eaf59089f691d89a0811fa355e9579fd44011dbe Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Thu, 16 Jun 2016 15:30:11 +0200
Subject: [PATCH] vga: add sr_vbe register set
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
Message-id: <1466091011-8095-2-git-send-email-kraxel@redhat.com>
Patchwork-id: 70639
O-Subject: [RHEL-7.3 qemu-kvm PATCH 1/1] vga: add sr_vbe register set
Bugzilla: 1347527
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Commit "fd3c136 vga: make sure vga register setup for vbe stays intact
(CVE-2016-3712)." causes a regression.  The win7 installer is unhappy
because it can't freely modify vga registers any more while in vbe mode.
This patch introduces a new sr_vbe register set.  The vbe_update_vgaregs
will fill sr_vbe[] instead of sr[].  Normal vga register reads and
writes go to sr[].  Any sr register read access happens through a new
sr() helper function which will read from sr_vbe[] with vbe active and
from sr[] otherwise.
This way we can allow guests update sr[] registers as they want, without
allowing them disrupt vbe video modes that way.
Cc: qemu-stable@nongnu.org
Reported-by: Thomas Lamprecht <thomas@lamprecht.org>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1463475294-14119-1-git-send-email-kraxel@redhat.com
(cherry picked from commit 94ef4f337fb614f18b765a8e0e878a4c23cdedcd)
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
Conflicts:
    hw/display/vga.c
[ RHEL-7 note: context differences in vga_update_memory_access ]
---
 hw/display/vga.c     | 50 ++++++++++++++++++++++++++++----------------------
 hw/display/vga_int.h |  1 +
 2 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index f049b26..4e3c3f3 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -173,6 +173,11 @@ static inline bool vbe_enabled(VGACommonState *s)
     return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED;
 }
+static inline uint8_t sr(VGACommonState *s, int idx)
+{
+    return vbe_enabled(s) ? s->sr_vbe[idx] : s->sr[idx];
+}
+
 static void vga_update_memory_access(VGACommonState *s)
 {
     MemoryRegion *region, *old_region = s->chain4_alias;
@@ -180,8 +185,8 @@ static void vga_update_memory_access(VGACommonState *s)
     s->chain4_alias = NULL;
-    if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==
-        VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
+    if ((sr(s, VGA_SEQ_PLANE_WRITE) & VGA_SR02_ALL_PLANES) ==
+        VGA_SR02_ALL_PLANES && sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
         offset = 0;
         switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {
         case 0:
@@ -257,7 +262,7 @@ static void vga_precise_update_retrace_info(VGACommonState *s)
           ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8);
     vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf;
-    clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1;
+    clocking_mode = (sr(s, VGA_SEQ_CLOCK_MODE) >> 3) & 1;
     clock_sel = (s->msr >> 2) & 3;
     dots = (s->msr & 1) ? 8 : 9;
@@ -513,7 +518,6 @@ 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);
         }
@@ -707,13 +711,13 @@ static void vbe_update_vgaregs(VGACommonState *s)
     if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) {
         shift_control = 0;
-        s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */
+        s->sr_vbe[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;
+        s->sr_vbe[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M;
         /* activate all planes */
-        s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
+        s->sr_vbe[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES;
     }
     s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) |
         (shift_control << 5);
@@ -863,7 +867,7 @@ uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr)
         break;
     }
-    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
+    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
         /* chain 4 mode : simplest access */
         assert(addr < s->vram_size);
         ret = s->vram_ptr[addr];
@@ -931,11 +935,11 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
         break;
     }
-    if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {
+    if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) {
         /* chain 4 mode : simplest access */
         plane = addr & 3;
         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
@@ -948,7 +952,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
         /* odd/even mode (aka text mode mapping) */
         plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1);
         mask = (1 << plane);
-        if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) {
+        if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) {
             addr = ((addr & ~1) << 1) | plane;
             if (addr >= s->vram_size) {
                 return;
@@ -1023,7 +1027,7 @@ void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val)
     do_write:
         /* mask data according to sr[2] */
-        mask = s->sr[VGA_SEQ_PLANE_WRITE];
+        mask = sr(s, 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) {
@@ -1314,10 +1318,10 @@ static void vga_get_text_resolution(VGACommonState *s, int *pwidth, int *pheight
     /* total width & height */
     cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
     cwidth = 8;
-    if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
+    if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
         cwidth = 9;
     }
-    if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
+    if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
         cwidth = 16; /* NOTE: no 18 pixel wide */
     }
     width = (s->cr[VGA_CRTC_H_DISP] + 1);
@@ -1373,7 +1377,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     int64_t now = qemu_get_clock_ms(vm_clock);
     /* compute font data address (in plane 2) */
-    v = s->sr[VGA_SEQ_CHARACTER_MAP];
+    v = sr(s, VGA_SEQ_CHARACTER_MAP);
     offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
     if (offset != s->font_offsets[0]) {
         s->font_offsets[0] = offset;
@@ -1744,11 +1748,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
     if (shift_control == 0) {
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             disp_width <<= 1;
         }
     } else if (shift_control == 1) {
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             disp_width <<= 1;
         }
     }
@@ -1788,7 +1792,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     if (shift_control == 0) {
         full_update |= update_palette16(s);
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             v = VGA_DRAW_LINE4D2;
         } else {
             v = VGA_DRAW_LINE4;
@@ -1796,7 +1800,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         bits = 4;
     } else if (shift_control == 1) {
         full_update |= update_palette16(s);
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) {
             v = VGA_DRAW_LINE2D2;
         } else {
             v = VGA_DRAW_LINE2;
@@ -1844,7 +1848,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 #if 0
     printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
            width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
-           s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]);
+           s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
 #endif
     addr1 = (s->start_addr * 4);
     bwidth = (width * bits + 7) / 8;
@@ -2003,6 +2007,7 @@ void vga_common_reset(VGACommonState *s)
 {
     s->sr_index = 0;
     memset(s->sr, '\0', sizeof(s->sr));
+    memset(s->sr_vbe, '\0', sizeof(s->sr_vbe));
     s->gr_index = 0;
     memset(s->gr, '\0', sizeof(s->gr));
     s->ar_index = 0;
@@ -2104,10 +2109,10 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
         /* total width & height */
         cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1;
         cw = 8;
-        if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) {
+        if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) {
             cw = 9;
         }
-        if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) {
+        if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) {
             cw = 16; /* NOTE: no 18 pixel wide */
         }
         width = (s->cr[VGA_CRTC_H_DISP] + 1);
@@ -2273,6 +2278,7 @@ static int vga_common_post_load(void *opaque, int version_id)
     /* force refresh */
     s->graphic_mode = -1;
+    vbe_update_vgaregs(s);
     return 0;
 }
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index 5a2f466..7c758ac 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -98,6 +98,7 @@ typedef struct VGACommonState {
     MemoryRegion *chain4_alias;
     uint8_t sr_index;
     uint8_t sr[256];
+    uint8_t sr_vbe[256];
     uint8_t gr_index;
     uint8_t gr[256];
     uint8_t ar_index;
--
1.8.3.1
SOURCES/kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch
New file
@@ -0,0 +1,57 @@
From 328d99710a005b9042c4d4c423f3f5a21f0e8ead Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 25 Jul 2016 12:55:36 +0200
Subject: [PATCH] virtio: error out if guest exceeds virtqueue size
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: <1469451336-20117-2-git-send-email-stefanha@redhat.com>
Patchwork-id: 71428
O-Subject: [virt-devel] [RHEL-7.3 EMBARGOED qemu-kvm PATCH 1/1] virtio: error out if guest exceeds virtqueue size
Bugzilla: 1359728
RH-Acked-by: Thomas Huth <thuth@redhat.com>
RH-Acked-by: Marc-AndrĂ© Lureau <mlureau@redhat.com>
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
A broken or malicious guest can submit more requests than the virtqueue
size permits.
The guest can submit requests without bothering to wait for completion
and is therefore not bound by virtqueue size.  This requires reusing
vring descriptors in more than one request, which is incorrect but
possible.  Processing a request allocates a VirtQueueElement and
therefore causes unbounded memory allocation controlled by the guest.
Exit with an error if the guest provides more requests than the
virtqueue size permits.  This bounds memory allocation and makes the
buggy guest visible to the user.
This patch fixes CVE-2016-5403.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/virtio/virtio.c | 5 +++++
 1 file changed, 5 insertions(+)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 132b5af..a861870 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -452,6 +452,11 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
     max = vq->vring.num;
+    if (vq->inuse >= max) {
+        error_report("Virtqueue size exceeded");
+        exit(1);
+    }
+
     i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
     if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
         vring_avail_event(vq, vring_avail_idx(vq));
--
1.8.3.1
SPECS/qemu-kvm.spec
@@ -76,7 +76,7 @@
Summary: QEMU is a FAST! processor emulator
Name: %{pkgname}%{?pkgsuffix}
Version: 1.5.3
Release: 105%{?dist}.4
Release: 105%{?dist}.7
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 10
License: GPLv2+ and LGPLv2+ and BSD
@@ -3181,6 +3181,12 @@
Patch1562: kvm-vga-update-vga-register-setup-on-vbe-changes.patch
# For bz#1331412 - EMBARGOED CVE-2016-3710 qemu-kvm: qemu: incorrect banked access bounds checking in vga module [rhel-7.2.z]
Patch1563: kvm-vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
# For bz#1347527 - Regression from CVE-2016-3712: windows installer fails to start
Patch1564: kvm-vga-add-sr_vbe-register-set.patch
# For bz#1359728 - EMBARGOED CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.2.z]
Patch1565: kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch
# For bz#1358996 - CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.2.z]
Patch1566: kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch
BuildRequires: zlib-devel
@@ -4957,6 +4963,9 @@
%patch1561 -p1
%patch1562 -p1
%patch1563 -p1
%patch1564 -p1
%patch1565 -p1
%patch1566 -p1
%build
buildarch="%{kvm_target}-softmmu"
@@ -5413,6 +5422,21 @@
%{_libdir}/pkgconfig/libcacard.pc
%changelog
* Tue Aug 02 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.7
- kvm-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch [bz#1358996]
- Resolves: bz#1358996
  (CVE-2016-5126 qemu-kvm: Qemu: block: iscsi: buffer overflow in iscsi_aio_ioctl [rhel-7.2.z])
* Wed Jul 27 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.6
- kvm-virtio-error-out-if-guest-exceeds-virtqueue-size.patch [bz#1359728]
- Resolves: bz#1359728
  (EMBARGOED CVE-2016-5403 qemu-kvm: Qemu: virtio: unbounded memory allocation on host via guest leading to DoS [rhel-7.2.z])
* Fri Jul 01 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.5
- kvm-vga-add-sr_vbe-register-set.patch [bz#1347527]
- Resolves: bz#1347527
  (Regression from CVE-2016-3712: windows installer fails to start)
* Tue May 03 2016 Miroslav Rezanina <mrezanin@redhat.com> - 1.5.3-105.el7_2.4
- kvm-vga-Remove-some-should-be-done-in-BIOS-comments.patch [bz#1331412]
- kvm-vga-fix-banked-access-bounds-checking-CVE-2016-3710.patch [bz#1331412]