[qemu] Migration CVEs: CVE-2014-0182 etc.

Cole Robinson crobinso at fedoraproject.org
Sun May 11 23:07:18 UTC 2014


commit 70114f9e561060efff73e19762d43ed170eb80da
Author: Cole Robinson <crobinso at redhat.com>
Date:   Sun May 11 19:07:44 2014 -0400

    Migration CVEs: CVE-2014-0182 etc.

 ...quit-accelerator-to-ctrl-shift-q-bz-10623.patch |    2 +-
 0002-vmstate-add-VMS_MUST_EXIST.patch              |   57 +++++++++++++++
 0003-vmstate-add-VMSTATE_VALIDATE.patch            |   33 +++++++++
 ...fix-buffer-overflow-on-invalid-state-load.patch |   59 +++++++++++++++
 ...out-of-bounds-buffer-write-on-invalid-sta.patch |   55 ++++++++++++++
 ...of-bounds-buffer-write-on-invalid-state-l.patch |   52 +++++++++++++
 ...-fix-buffer-overrun-on-invalid-state-load.patch |   36 +++++++++
 ...-fix-buffer-overrun-on-invalid-state-load.patch |   51 +++++++++++++
 ..._aer.c-fix-buffer-overruns-on-invalid-sta.patch |   55 ++++++++++++++
 ...2-fix-buffer-overun-on-invalid-state-load.patch |   50 +++++++++++++
 ...x-buffer-overflow-in-target-arm-machine.c.patch |   52 +++++++++++++
 ...void-buffer-overrun-on-incoming-migration.patch |   40 ++++++++++
 0013-virtio-validate-num_sg-when-mapping.patch     |   41 +++++++++++
 ...void-buffer-overrun-on-incoming-migration.patch |   51 +++++++++++++
 ...3-fix-buffer-overun-on-invalid-state-load.patch |   77 ++++++++++++++++++++
 ...-fix-buffer-overrun-on-invalid-state-load.patch |   50 +++++++++++++
 ...-fix-buffer-overrun-on-invalid-state-load.patch |   54 ++++++++++++++
 ...-fix-buffer-overrun-on-invalid-state-load.patch |   67 +++++++++++++++++
 ...MSTATE_INT32_LE-VMSTATE_INT32_POSITIVE_LE.patch |   65 +++++++++++++++++
 ...-check-setup_index-setup_len-in-post_load.patch |   38 ++++++++++
 ...-fix-buffer-overrun-on-invalid-state-load.patch |   41 +++++++++++
 ...void-buffer-overrun-on-incoming-migration.patch |   72 ++++++++++++++++++
 ...io-net-out-of-bounds-buffer-write-on-load.patch |   55 ++++++++++++++
 0024-virtio-validate-config_len-on-load.patch      |   52 +++++++++++++
 qemu.spec                                          |   53 +++++++++++++-
 25 files changed, 1256 insertions(+), 2 deletions(-)
---
diff --git a/0001-Change-gtk-quit-accelerator-to-ctrl-shift-q-bz-10623.patch b/0001-Change-gtk-quit-accelerator-to-ctrl-shift-q-bz-10623.patch
index 9c0524d..3fc7beb 100644
--- a/0001-Change-gtk-quit-accelerator-to-ctrl-shift-q-bz-10623.patch
+++ b/0001-Change-gtk-quit-accelerator-to-ctrl-shift-q-bz-10623.patch
@@ -1,4 +1,4 @@
-From 6b4fcd4bb73c86c7754bcc912a557ba62180ae0b Mon Sep 17 00:00:00 2001
+From 9d8e4e500dca987531be3666422f17c9486940b2 Mon Sep 17 00:00:00 2001
 From: Cole Robinson <crobinso at redhat.com>
 Date: Wed, 19 Mar 2014 14:57:27 -0400
 Subject: [PATCH] Change gtk quit accelerator to ctrl+shift+q (bz 1062393)
diff --git a/0002-vmstate-add-VMS_MUST_EXIST.patch b/0002-vmstate-add-VMS_MUST_EXIST.patch
new file mode 100644
index 0000000..073abd8
--- /dev/null
+++ b/0002-vmstate-add-VMS_MUST_EXIST.patch
@@ -0,0 +1,57 @@
+From 105071cc70a454680e6bf11e2d9d7b73c7ce7491 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:50:31 +0300
+Subject: [PATCH] vmstate: add VMS_MUST_EXIST
+
+Can be used to verify a required field exists or validate
+state in some other way.
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 5bf81c8d63db0216a4d29dc87f9ce530bb791dd1)
+---
+ include/migration/vmstate.h |  1 +
+ vmstate.c                   | 10 ++++++++++
+ 2 files changed, 11 insertions(+)
+
+diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
+index e7e1705..de970ab 100644
+--- a/include/migration/vmstate.h
++++ b/include/migration/vmstate.h
+@@ -100,6 +100,7 @@ enum VMStateFlags {
+     VMS_MULTIPLY         = 0x200,  /* multiply "size" field by field_size */
+     VMS_VARRAY_UINT8     = 0x400,  /* Array with size in uint8_t field*/
+     VMS_VARRAY_UINT32    = 0x800,  /* Array with size in uint32_t field*/
++    VMS_MUST_EXIST       = 0x1000, /* Field must exist in input */
+ };
+ 
+ typedef struct {
+diff --git a/vmstate.c b/vmstate.c
+index b689f2f..d856319 100644
+--- a/vmstate.c
++++ b/vmstate.c
+@@ -78,6 +78,10 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
+                     return ret;
+                 }
+             }
++        } else if (field->flags & VMS_MUST_EXIST) {
++            fprintf(stderr, "Input validation failed: %s/%s\n",
++                    vmsd->name, field->name);
++            return -1;
+         }
+         field++;
+     }
+@@ -138,6 +142,12 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
+                     field->info->put(f, addr, size);
+                 }
+             }
++        } else {
++            if (field->flags & VMS_MUST_EXIST) {
++                fprintf(stderr, "Output state validation failed: %s/%s\n",
++                        vmsd->name, field->name);
++                assert(!(field->flags & VMS_MUST_EXIST));
++            }
+         }
+         field++;
+     }
diff --git a/0003-vmstate-add-VMSTATE_VALIDATE.patch b/0003-vmstate-add-VMSTATE_VALIDATE.patch
new file mode 100644
index 0000000..775a9ab
--- /dev/null
+++ b/0003-vmstate-add-VMSTATE_VALIDATE.patch
@@ -0,0 +1,33 @@
+From d9e0cb134eefe5104b404b91eaf969a2cd74bd9f Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:50:35 +0300
+Subject: [PATCH] vmstate: add VMSTATE_VALIDATE
+
+Validate state using VMS_ARRAY with num = 0 and VMS_MUST_EXIST
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 4082f0889ba04678fc14816c53e1b9251ea9207e)
+---
+ include/migration/vmstate.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
+index de970ab..5b71370 100644
+--- a/include/migration/vmstate.h
++++ b/include/migration/vmstate.h
+@@ -204,6 +204,14 @@ extern const VMStateInfo vmstate_info_bitmap;
+     .offset       = vmstate_offset_value(_state, _field, _type),     \
+ }
+ 
++/* Validate state using a boolean predicate. */
++#define VMSTATE_VALIDATE(_name, _test) { \
++    .name         = (_name),                                         \
++    .field_exists = (_test),                                         \
++    .flags        = VMS_ARRAY | VMS_MUST_EXIST,                      \
++    .num          = 0, /* 0 elements: no data, only run _test */     \
++}
++
+ #define VMSTATE_POINTER(_field, _state, _version, _info, _type) {    \
+     .name       = (stringify(_field)),                               \
+     .version_id = (_version),                                        \
diff --git a/0004-virtio-net-fix-buffer-overflow-on-invalid-state-load.patch b/0004-virtio-net-fix-buffer-overflow-on-invalid-state-load.patch
new file mode 100644
index 0000000..1b315c5
--- /dev/null
+++ b/0004-virtio-net-fix-buffer-overflow-on-invalid-state-load.patch
@@ -0,0 +1,59 @@
+From ea96c6a9c91da1923aa922a781fd7abbf9f51b6c Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:50:39 +0300
+Subject: [PATCH] virtio-net: fix buffer overflow on invalid state load
+
+CVE-2013-4148 QEMU 1.0 integer conversion in
+virtio_net_load()@hw/net/virtio-net.c
+
+Deals with loading a corrupted savevm image.
+
+>         n->mac_table.in_use = qemu_get_be32(f);
+
+in_use is int so it can get negative when assigned 32bit unsigned value.
+
+>         /* MAC_TABLE_ENTRIES may be different from the saved image */
+>         if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
+
+passing this check ^^^
+
+>             qemu_get_buffer(f, n->mac_table.macs,
+>                             n->mac_table.in_use * ETH_ALEN);
+
+with good in_use value, "n->mac_table.in_use * ETH_ALEN" can get
+positive and bigger than mac_table.macs. For example 0x81000000
+satisfies this condition when ETH_ALEN is 6.
+
+Fix it by making the value unsigned.
+For consistency, change first_multi as well.
+
+Note: all call sites were audited to confirm that
+making them unsigned didn't cause any issues:
+it turns out we actually never do math on them,
+so it's easy to validate because both values are
+always <= MAC_TABLE_ENTRIES.
+
+Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Laszlo Ersek <lersek at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 71f7fe48e10a8437c9d42d859389f37157f59980)
+---
+ include/hw/virtio/virtio-net.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
+index df60f16..4b32440 100644
+--- a/include/hw/virtio/virtio-net.h
++++ b/include/hw/virtio/virtio-net.h
+@@ -176,8 +176,8 @@ typedef struct VirtIONet {
+     uint8_t nobcast;
+     uint8_t vhost_started;
+     struct {
+-        int in_use;
+-        int first_multi;
++        uint32_t in_use;
++        uint32_t first_multi;
+         uint8_t multi_overflow;
+         uint8_t uni_overflow;
+         uint8_t *macs;
diff --git a/0005-virtio-net-out-of-bounds-buffer-write-on-invalid-sta.patch b/0005-virtio-net-out-of-bounds-buffer-write-on-invalid-sta.patch
new file mode 100644
index 0000000..3648d73
--- /dev/null
+++ b/0005-virtio-net-out-of-bounds-buffer-write-on-invalid-sta.patch
@@ -0,0 +1,55 @@
+From 9229c44bfa3549085ac68265d9be95a8552c4fa4 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:50:56 +0300
+Subject: [PATCH] virtio-net: out-of-bounds buffer write on invalid state load
+
+CVE-2013-4150 QEMU 1.5.0 out-of-bounds buffer write in
+virtio_net_load()@hw/net/virtio-net.c
+
+This code is in hw/net/virtio-net.c:
+
+    if (n->max_queues > 1) {
+        if (n->max_queues != qemu_get_be16(f)) {
+            error_report("virtio-net: different max_queues ");
+            return -1;
+        }
+
+        n->curr_queues = qemu_get_be16(f);
+        for (i = 1; i < n->curr_queues; i++) {
+            n->vqs[i].tx_waiting = qemu_get_be32(f);
+        }
+    }
+
+Number of vqs is max_queues, so if we get invalid input here,
+for example if max_queues = 2, curr_queues = 3, we get
+write beyond end of the buffer, with data that comes from
+wire.
+
+This might be used to corrupt qemu memory in hard to predict ways.
+Since we have lots of function pointers around, RCE might be possible.
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Acked-by: Jason Wang <jasowang at redhat.com>
+Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit eea750a5623ddac7a61982eec8f1c93481857578)
+---
+ hw/net/virtio-net.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index 33bd233..0a8cb40 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -1407,6 +1407,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
+         }
+ 
+         n->curr_queues = qemu_get_be16(f);
++        if (n->curr_queues > n->max_queues) {
++            error_report("virtio-net: curr_queues %x > max_queues %x",
++                         n->curr_queues, n->max_queues);
++            return -1;
++        }
+         for (i = 1; i < n->curr_queues; i++) {
+             n->vqs[i].tx_waiting = qemu_get_be32(f);
+         }
diff --git a/0006-virtio-out-of-bounds-buffer-write-on-invalid-state-l.patch b/0006-virtio-out-of-bounds-buffer-write-on-invalid-state-l.patch
new file mode 100644
index 0000000..c47af93
--- /dev/null
+++ b/0006-virtio-out-of-bounds-buffer-write-on-invalid-state-l.patch
@@ -0,0 +1,52 @@
+From 23f0db5c309893195025bc75402f3f9e1b4de743 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:14 +0300
+Subject: [PATCH] virtio: out-of-bounds buffer write on invalid state load
+
+CVE-2013-4151 QEMU 1.0 out-of-bounds buffer write in
+virtio_load at hw/virtio/virtio.c
+
+So we have this code since way back when:
+
+    num = qemu_get_be32(f);
+
+    for (i = 0; i < num; i++) {
+        vdev->vq[i].vring.num = qemu_get_be32(f);
+
+array of vqs has size VIRTIO_PCI_QUEUE_MAX, so
+on invalid input this will write beyond end of buffer.
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit cc45995294b92d95319b4782750a3580cabdbc0c)
+---
+ hw/virtio/virtio.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index aeabf3a..05f05e7 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -891,7 +891,8 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val)
+ 
+ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
+ {
+-    int num, i, ret;
++    int i, ret;
++    uint32_t num;
+     uint32_t features;
+     uint32_t supported_features;
+     BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
+@@ -919,6 +920,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
+ 
+     num = qemu_get_be32(f);
+ 
++    if (num > VIRTIO_PCI_QUEUE_MAX) {
++        error_report("Invalid number of PCI queues: 0x%x", num);
++        return -1;
++    }
++
+     for (i = 0; i < num; i++) {
+         vdev->vq[i].vring.num = qemu_get_be32(f);
+         if (k->has_variable_vring_alignment) {
diff --git a/0007-ahci-fix-buffer-overrun-on-invalid-state-load.patch b/0007-ahci-fix-buffer-overrun-on-invalid-state-load.patch
new file mode 100644
index 0000000..07a379c
--- /dev/null
+++ b/0007-ahci-fix-buffer-overrun-on-invalid-state-load.patch
@@ -0,0 +1,36 @@
+From 95fa012ed61e1e8b88d701b8f75b38dc5edb16e2 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:18 +0300
+Subject: [PATCH] ahci: fix buffer overrun on invalid state load
+
+CVE-2013-4526
+
+Within hw/ide/ahci.c, VARRAY refers to ports which is also loaded.  So
+we use the old version of ports to read the array but then allow any
+value for ports.  This can cause the code to overflow.
+
+There's no reason to migrate ports - it never changes.
+So just make sure it matches.
+
+Reported-by: Anthony Liguori <anthony at codemonkey.ws>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit ae2158ad6ce0845b2fae2a22aa7f19c0d7a71ce5)
+---
+ hw/ide/ahci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
+index bfe633f..457a7a1 100644
+--- a/hw/ide/ahci.c
++++ b/hw/ide/ahci.c
+@@ -1293,7 +1293,7 @@ const VMStateDescription vmstate_ahci = {
+         VMSTATE_UINT32(control_regs.impl, AHCIState),
+         VMSTATE_UINT32(control_regs.version, AHCIState),
+         VMSTATE_UINT32(idp_index, AHCIState),
+-        VMSTATE_INT32(ports, AHCIState),
++        VMSTATE_INT32_EQUAL(ports, AHCIState),
+         VMSTATE_END_OF_LIST()
+     },
+ };
diff --git a/0008-hpet-fix-buffer-overrun-on-invalid-state-load.patch b/0008-hpet-fix-buffer-overrun-on-invalid-state-load.patch
new file mode 100644
index 0000000..fa1c624
--- /dev/null
+++ b/0008-hpet-fix-buffer-overrun-on-invalid-state-load.patch
@@ -0,0 +1,51 @@
+From 5e0e0a12887c9e70356c23d20b08b08eabd4a6df Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:23 +0300
+Subject: [PATCH] hpet: fix buffer overrun on invalid state load
+
+CVE-2013-4527 hw/timer/hpet.c buffer overrun
+
+hpet is a VARRAY with a uint8 size but static array of 32
+
+To fix, make sure num_timers is valid using VMSTATE_VALID hook.
+
+Reported-by: Anthony Liguori <anthony at codemonkey.ws>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 3f1c49e2136fa08ab1ef3183fd55def308829584)
+---
+ hw/timer/hpet.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
+index e15d6bc..2792f89 100644
+--- a/hw/timer/hpet.c
++++ b/hw/timer/hpet.c
+@@ -239,6 +239,18 @@ static int hpet_pre_load(void *opaque)
+     return 0;
+ }
+ 
++static bool hpet_validate_num_timers(void *opaque, int version_id)
++{
++    HPETState *s = opaque;
++
++    if (s->num_timers < HPET_MIN_TIMERS) {
++        return false;
++    } else if (s->num_timers > HPET_MAX_TIMERS) {
++        return false;
++    }
++    return true;
++}
++
+ static int hpet_post_load(void *opaque, int version_id)
+ {
+     HPETState *s = opaque;
+@@ -307,6 +319,7 @@ static const VMStateDescription vmstate_hpet = {
+         VMSTATE_UINT64(isr, HPETState),
+         VMSTATE_UINT64(hpet_counter, HPETState),
+         VMSTATE_UINT8_V(num_timers, HPETState, 2),
++        VMSTATE_VALIDATE("num_timers in range", hpet_validate_num_timers),
+         VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
+                                     vmstate_hpet_timer, HPETTimer),
+         VMSTATE_END_OF_LIST()
diff --git a/0009-hw-pci-pcie_aer.c-fix-buffer-overruns-on-invalid-sta.patch b/0009-hw-pci-pcie_aer.c-fix-buffer-overruns-on-invalid-sta.patch
new file mode 100644
index 0000000..5b22295
--- /dev/null
+++ b/0009-hw-pci-pcie_aer.c-fix-buffer-overruns-on-invalid-sta.patch
@@ -0,0 +1,55 @@
+From b6f53085cc618bc7e58be702afacad1b5dcae5ba Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:31 +0300
+Subject: [PATCH] hw/pci/pcie_aer.c: fix buffer overruns on invalid state load
+
+4) CVE-2013-4529
+hw/pci/pcie_aer.c    pcie aer log can overrun the buffer if log_num is
+                     too large
+
+There are two issues in this file:
+1. log_max from remote can be larger than on local
+then buffer will overrun with data coming from state file.
+2. log_num can be larger then we get data corruption
+again with an overflow but not adversary controlled.
+
+Fix both issues.
+
+Reported-by: Anthony Liguori <anthony at codemonkey.ws>
+Reported-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 5f691ff91d323b6f97c6600405a7f9dc115a0ad1)
+---
+ hw/pci/pcie_aer.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
+index 991502e..535be2c 100644
+--- a/hw/pci/pcie_aer.c
++++ b/hw/pci/pcie_aer.c
+@@ -795,6 +795,13 @@ static const VMStateDescription vmstate_pcie_aer_err = {
+     }
+ };
+ 
++static bool pcie_aer_state_log_num_valid(void *opaque, int version_id)
++{
++    PCIEAERLog *s = opaque;
++
++    return s->log_num <= s->log_max;
++}
++
+ const VMStateDescription vmstate_pcie_aer_log = {
+     .name = "PCIE_AER_ERROR_LOG",
+     .version_id = 1,
+@@ -802,7 +809,8 @@ const VMStateDescription vmstate_pcie_aer_log = {
+     .minimum_version_id_old = 1,
+     .fields     = (VMStateField[]) {
+         VMSTATE_UINT16(log_num, PCIEAERLog),
+-        VMSTATE_UINT16(log_max, PCIEAERLog),
++        VMSTATE_UINT16_EQUAL(log_max, PCIEAERLog),
++        VMSTATE_VALIDATE("log_num <= log_max", pcie_aer_state_log_num_valid),
+         VMSTATE_STRUCT_VARRAY_POINTER_UINT16(log, PCIEAERLog, log_num,
+                               vmstate_pcie_aer_err, PCIEAERErr),
+         VMSTATE_END_OF_LIST()
diff --git a/0010-pl022-fix-buffer-overun-on-invalid-state-load.patch b/0010-pl022-fix-buffer-overun-on-invalid-state-load.patch
new file mode 100644
index 0000000..f48fa74
--- /dev/null
+++ b/0010-pl022-fix-buffer-overun-on-invalid-state-load.patch
@@ -0,0 +1,50 @@
+From 872fc04ecd90e0ca4d8ac4565b3a9f246c070873 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:35 +0300
+Subject: [PATCH] pl022: fix buffer overun on invalid state load
+
+CVE-2013-4530
+
+pl022.c did not bounds check tx_fifo_head and
+rx_fifo_head after loading them from file and
+before they are used to dereference array.
+
+Reported-by: Michael S. Tsirkin <mst at redhat.com
+Reported-by: Anthony Liguori <anthony at codemonkey.ws>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit d8d0a0bc7e194300e53a346d25fe5724fd588387)
+---
+ hw/ssi/pl022.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
+index fd479ef..b19bc71 100644
+--- a/hw/ssi/pl022.c
++++ b/hw/ssi/pl022.c
+@@ -240,11 +240,25 @@ static const MemoryRegionOps pl022_ops = {
+     .endianness = DEVICE_NATIVE_ENDIAN,
+ };
+ 
++static int pl022_post_load(void *opaque, int version_id)
++{
++    PL022State *s = opaque;
++
++    if (s->tx_fifo_head < 0 ||
++        s->tx_fifo_head >= ARRAY_SIZE(s->tx_fifo) ||
++        s->rx_fifo_head < 0 ||
++        s->rx_fifo_head >= ARRAY_SIZE(s->rx_fifo)) {
++        return -1;
++    }
++    return 0;
++}
++
+ static const VMStateDescription vmstate_pl022 = {
+     .name = "pl022_ssp",
+     .version_id = 1,
+     .minimum_version_id = 1,
+     .minimum_version_id_old = 1,
++    .post_load = pl022_post_load,
+     .fields      = (VMStateField[]) {
+         VMSTATE_UINT32(cr0, PL022State),
+         VMSTATE_UINT32(cr1, PL022State),
diff --git a/0011-vmstate-fix-buffer-overflow-in-target-arm-machine.c.patch b/0011-vmstate-fix-buffer-overflow-in-target-arm-machine.c.patch
new file mode 100644
index 0000000..46a77b0
--- /dev/null
+++ b/0011-vmstate-fix-buffer-overflow-in-target-arm-machine.c.patch
@@ -0,0 +1,52 @@
+From acf45756e165664f6d70025c02ddca563adee496 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:42 +0300
+Subject: [PATCH] vmstate: fix buffer overflow in target-arm/machine.c
+
+CVE-2013-4531
+
+cpreg_vmstate_indexes is a VARRAY_INT32. A negative value for
+cpreg_vmstate_array_len will cause a buffer overflow.
+
+VMSTATE_INT32_LE was supposed to protect against this
+but doesn't because it doesn't validate that input is
+non-negative.
+
+Fix this macro to valide the value appropriately.
+
+The only other user of VMSTATE_INT32_LE doesn't
+ever use negative numbers so it doesn't care.
+
+Reported-by: Anthony Liguori <anthony at codemonkey.ws>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit d2ef4b61fe6d33d2a5dcf100a9b9440de341ad62)
+---
+ vmstate.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/vmstate.c b/vmstate.c
+index d856319..105f184 100644
+--- a/vmstate.c
++++ b/vmstate.c
+@@ -333,8 +333,9 @@ const VMStateInfo vmstate_info_int32_equal = {
+     .put  = put_int32,
+ };
+ 
+-/* 32 bit int. Check that the received value is less than or equal to
+-   the one in the field */
++/* 32 bit int. Check that the received value is non-negative
++ * and less than or equal to the one in the field.
++ */
+ 
+ static int get_int32_le(QEMUFile *f, void *pv, size_t size)
+ {
+@@ -342,7 +343,7 @@ static int get_int32_le(QEMUFile *f, void *pv, size_t size)
+     int32_t loaded;
+     qemu_get_sbe32s(f, &loaded);
+ 
+-    if (loaded <= *cur) {
++    if (loaded >= 0 && loaded <= *cur) {
+         *cur = loaded;
+         return 0;
+     }
diff --git a/0012-virtio-avoid-buffer-overrun-on-incoming-migration.patch b/0012-virtio-avoid-buffer-overrun-on-incoming-migration.patch
new file mode 100644
index 0000000..69bdf95
--- /dev/null
+++ b/0012-virtio-avoid-buffer-overrun-on-incoming-migration.patch
@@ -0,0 +1,40 @@
+From 9b5cc034e1ed5b2ebc133029d4f865f186c6b895 Mon Sep 17 00:00:00 2001
+From: Michael Roth <mdroth at linux.vnet.ibm.com>
+Date: Thu, 3 Apr 2014 19:51:46 +0300
+Subject: [PATCH] virtio: avoid buffer overrun on incoming migration
+
+CVE-2013-6399
+
+vdev->queue_sel is read from the wire, and later used in the
+emulation code as an index into vdev->vq[]. If the value of
+vdev->queue_sel exceeds the length of vdev->vq[], currently
+allocated to be VIRTIO_PCI_QUEUE_MAX elements, subsequent PIO
+operations such as VIRTIO_PCI_QUEUE_PFN can be used to overrun
+the buffer with arbitrary data originating from the source.
+
+Fix this by failing migration if the value from the wire exceeds
+VIRTIO_PCI_QUEUE_MAX.
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 4b53c2c72cb5541cf394033b528a6fe2a86c0ac1)
+---
+ hw/virtio/virtio.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 05f05e7..0072542 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -907,6 +907,9 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
+     qemu_get_8s(f, &vdev->status);
+     qemu_get_8s(f, &vdev->isr);
+     qemu_get_be16s(f, &vdev->queue_sel);
++    if (vdev->queue_sel >= VIRTIO_PCI_QUEUE_MAX) {
++        return -1;
++    }
+     qemu_get_be32s(f, &features);
+ 
+     if (virtio_set_features(vdev, features) < 0) {
diff --git a/0013-virtio-validate-num_sg-when-mapping.patch b/0013-virtio-validate-num_sg-when-mapping.patch
new file mode 100644
index 0000000..91de06c
--- /dev/null
+++ b/0013-virtio-validate-num_sg-when-mapping.patch
@@ -0,0 +1,41 @@
+From f1344659fd93ea0dfb9d8d1af25993e57584c773 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:53 +0300
+Subject: [PATCH] virtio: validate num_sg when mapping
+
+CVE-2013-4535
+CVE-2013-4536
+
+Both virtio-block and virtio-serial read,
+VirtQueueElements are read in as buffers, and passed to
+virtqueue_map_sg(), where num_sg is taken from the wire and can force
+writes to indicies beyond VIRTQUEUE_MAX_SIZE.
+
+To fix, validate num_sg.
+
+Reported-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Cc: Amit Shah <amit.shah at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 36cf2a37132c7f01fa9adb5f95f5312b27742fd4)
+---
+ hw/virtio/virtio.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index 0072542..a70169a 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -430,6 +430,12 @@ void virtqueue_map_sg(struct iovec *sg, hwaddr *addr,
+     unsigned int i;
+     hwaddr len;
+ 
++    if (num_sg >= VIRTQUEUE_MAX_SIZE) {
++        error_report("virtio: map attempt out of bounds: %zd > %d",
++                     num_sg, VIRTQUEUE_MAX_SIZE);
++        exit(1);
++    }
++
+     for (i = 0; i < num_sg; i++) {
+         len = sg[i].iov_len;
+         sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
diff --git a/0014-pxa2xx-avoid-buffer-overrun-on-incoming-migration.patch b/0014-pxa2xx-avoid-buffer-overrun-on-incoming-migration.patch
new file mode 100644
index 0000000..94d2d4d
--- /dev/null
+++ b/0014-pxa2xx-avoid-buffer-overrun-on-incoming-migration.patch
@@ -0,0 +1,51 @@
+From 43b30dec4d07aa81ff5f2dc3b0a064fa589fd3af Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:51:57 +0300
+Subject: [PATCH] pxa2xx: avoid buffer overrun on incoming migration
+
+CVE-2013-4533
+
+s->rx_level is read from the wire and used to determine how many bytes
+to subsequently read into s->rx_fifo[]. If s->rx_level exceeds the
+length of s->rx_fifo[] the buffer can be overrun with arbitrary data
+from the wire.
+
+Fix this by validating rx_level against the size of s->rx_fifo.
+
+Cc: Don Koch <dkoch at verizon.com>
+Reported-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Reviewed-by: Don Koch <dkoch at verizon.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit caa881abe0e01f9931125a0977ec33c5343e4aa7)
+---
+ hw/arm/pxa2xx.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
+index 0429148..e0cd847 100644
+--- a/hw/arm/pxa2xx.c
++++ b/hw/arm/pxa2xx.c
+@@ -732,7 +732,7 @@ static void pxa2xx_ssp_save(QEMUFile *f, void *opaque)
+ static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
+ {
+     PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;
+-    int i;
++    int i, v;
+ 
+     s->enable = qemu_get_be32(f);
+ 
+@@ -746,7 +746,11 @@ static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
+     qemu_get_8s(f, &s->ssrsa);
+     qemu_get_8s(f, &s->ssacd);
+ 
+-    s->rx_level = qemu_get_byte(f);
++    v = qemu_get_byte(f);
++    if (v < 0 || v > ARRAY_SIZE(s->rx_fifo)) {
++        return -EINVAL;
++    }
++    s->rx_level = v;
+     s->rx_start = 0;
+     for (i = 0; i < s->rx_level; i ++)
+         s->rx_fifo[i] = qemu_get_byte(f);
diff --git a/0015-ssd0323-fix-buffer-overun-on-invalid-state-load.patch b/0015-ssd0323-fix-buffer-overun-on-invalid-state-load.patch
new file mode 100644
index 0000000..c0bc8e9
--- /dev/null
+++ b/0015-ssd0323-fix-buffer-overun-on-invalid-state-load.patch
@@ -0,0 +1,77 @@
+From 0cbd8c5754d6f56b53717e92353772777a799b87 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:52:05 +0300
+Subject: [PATCH] ssd0323: fix buffer overun on invalid state load
+
+CVE-2013-4538
+
+s->cmd_len used as index in ssd0323_transfer() to store 32-bit field.
+Possible this field might then be supplied by guest to overwrite a
+return addr somewhere. Same for row/col fields, which are indicies into
+framebuffer array.
+
+To fix validate after load.
+
+Additionally, validate that the row/col_start/end are within bounds;
+otherwise the guest can provoke an overrun by either setting the _end
+field so large that the row++ increments just walk off the end of the
+array, or by setting the _start value to something bogus and then
+letting the "we hit end of row" logic reset row to row_start.
+
+For completeness, validate mode as well.
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit ead7a57df37d2187813a121308213f41591bd811)
+---
+ hw/display/ssd0323.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c
+index 971152e..9727007 100644
+--- a/hw/display/ssd0323.c
++++ b/hw/display/ssd0323.c
+@@ -312,18 +312,42 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
+         return -EINVAL;
+ 
+     s->cmd_len = qemu_get_be32(f);
++    if (s->cmd_len < 0 || s->cmd_len > ARRAY_SIZE(s->cmd_data)) {
++        return -EINVAL;
++    }
+     s->cmd = qemu_get_be32(f);
+     for (i = 0; i < 8; i++)
+         s->cmd_data[i] = qemu_get_be32(f);
+     s->row = qemu_get_be32(f);
++    if (s->row < 0 || s->row >= 80) {
++        return -EINVAL;
++    }
+     s->row_start = qemu_get_be32(f);
++    if (s->row_start < 0 || s->row_start >= 80) {
++        return -EINVAL;
++    }
+     s->row_end = qemu_get_be32(f);
++    if (s->row_end < 0 || s->row_end >= 80) {
++        return -EINVAL;
++    }
+     s->col = qemu_get_be32(f);
++    if (s->col < 0 || s->col >= 64) {
++        return -EINVAL;
++    }
+     s->col_start = qemu_get_be32(f);
++    if (s->col_start < 0 || s->col_start >= 64) {
++        return -EINVAL;
++    }
+     s->col_end = qemu_get_be32(f);
++    if (s->col_end < 0 || s->col_end >= 64) {
++        return -EINVAL;
++    }
+     s->redraw = qemu_get_be32(f);
+     s->remap = qemu_get_be32(f);
+     s->mode = qemu_get_be32(f);
++    if (s->mode != SSD0323_CMD && s->mode != SSD0323_DATA) {
++        return -EINVAL;
++    }
+     qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
+ 
+     ss->cs = qemu_get_be32(f);
diff --git a/0016-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch b/0016-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch
new file mode 100644
index 0000000..33fc0c7
--- /dev/null
+++ b/0016-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch
@@ -0,0 +1,50 @@
+From 984fcc9ad2abc4429422c045d68e17f1eb1fa4b2 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:52:09 +0300
+Subject: [PATCH] tsc210x: fix buffer overrun on invalid state load
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2013-4539
+
+s->precision, nextprecision, function and nextfunction
+come from wire and are used
+as idx into resolution[] in TSC_CUT_RESOLUTION.
+
+Validate after load to avoid buffer overrun.
+
+Cc: Andreas Färber <afaerber at suse.de>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 5193be3be35f29a35bc465036cd64ad60d43385f)
+---
+ hw/input/tsc210x.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
+index 485c9e5..aa5b688 100644
+--- a/hw/input/tsc210x.c
++++ b/hw/input/tsc210x.c
+@@ -1070,9 +1070,21 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
+     s->enabled = qemu_get_byte(f);
+     s->host_mode = qemu_get_byte(f);
+     s->function = qemu_get_byte(f);
++    if (s->function < 0 || s->function >= ARRAY_SIZE(mode_regs)) {
++        return -EINVAL;
++    }
+     s->nextfunction = qemu_get_byte(f);
++    if (s->nextfunction < 0 || s->nextfunction >= ARRAY_SIZE(mode_regs)) {
++        return -EINVAL;
++    }
+     s->precision = qemu_get_byte(f);
++    if (s->precision < 0 || s->precision >= ARRAY_SIZE(resolution)) {
++        return -EINVAL;
++    }
+     s->nextprecision = qemu_get_byte(f);
++    if (s->nextprecision < 0 || s->nextprecision >= ARRAY_SIZE(resolution)) {
++        return -EINVAL;
++    }
+     s->filter = qemu_get_byte(f);
+     s->pin_func = qemu_get_byte(f);
+     s->ref = qemu_get_byte(f);
diff --git a/0017-zaurus-fix-buffer-overrun-on-invalid-state-load.patch b/0017-zaurus-fix-buffer-overrun-on-invalid-state-load.patch
new file mode 100644
index 0000000..9b442d4
--- /dev/null
+++ b/0017-zaurus-fix-buffer-overrun-on-invalid-state-load.patch
@@ -0,0 +1,54 @@
+From 985b046012f258fd5a2164fb85e9d792f574697c Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:52:13 +0300
+Subject: [PATCH] zaurus: fix buffer overrun on invalid state load
+
+CVE-2013-4540
+
+Within scoop_gpio_handler_update, if prev_level has a high bit set, then
+we get bit > 16 and that causes a buffer overrun.
+
+Since prev_level comes from wire indirectly, this can
+happen on invalid state load.
+
+Similarly for gpio_level and gpio_dir.
+
+To fix, limit to 16 bit.
+
+Reported-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 52f91c3723932f8340fe36c8ec8b18a757c37b2b)
+---
+ hw/gpio/zaurus.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c
+index dc79a8b..8e2ce04 100644
+--- a/hw/gpio/zaurus.c
++++ b/hw/gpio/zaurus.c
+@@ -203,6 +203,15 @@ static bool is_version_0 (void *opaque, int version_id)
+     return version_id == 0;
+ }
+ 
++static bool vmstate_scoop_validate(void *opaque, int version_id)
++{
++    ScoopInfo *s = opaque;
++
++    return !(s->prev_level & 0xffff0000) &&
++        !(s->gpio_level & 0xffff0000) &&
++        !(s->gpio_dir & 0xffff0000);
++}
++
+ static const VMStateDescription vmstate_scoop_regs = {
+     .name = "scoop",
+     .version_id = 1,
+@@ -215,6 +224,7 @@ static const VMStateDescription vmstate_scoop_regs = {
+         VMSTATE_UINT32(gpio_level, ScoopInfo),
+         VMSTATE_UINT32(gpio_dir, ScoopInfo),
+         VMSTATE_UINT32(prev_level, ScoopInfo),
++        VMSTATE_VALIDATE("irq levels are 16 bit", vmstate_scoop_validate),
+         VMSTATE_UINT16(mcr, ScoopInfo),
+         VMSTATE_UINT16(cdr, ScoopInfo),
+         VMSTATE_UINT16(ccr, ScoopInfo),
diff --git a/0018-virtio-scsi-fix-buffer-overrun-on-invalid-state-load.patch b/0018-virtio-scsi-fix-buffer-overrun-on-invalid-state-load.patch
new file mode 100644
index 0000000..6c8218d
--- /dev/null
+++ b/0018-virtio-scsi-fix-buffer-overrun-on-invalid-state-load.patch
@@ -0,0 +1,67 @@
+From 579bb2000dbcd8a415660e76d31f521d87ac1302 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:52:17 +0300
+Subject: [PATCH] virtio-scsi: fix buffer overrun on invalid state load
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2013-4542
+
+hw/scsi/scsi-bus.c invokes load_request.
+
+ virtio_scsi_load_request does:
+    qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
+
+this probably can make elem invalid, for example,
+make in_num or out_num huge, then:
+
+    virtio_scsi_parse_req(s, vs->cmd_vqs[n], req);
+
+will do:
+
+    if (req->elem.out_num > 1) {
+        qemu_sgl_init_external(req, &req->elem.out_sg[1],
+                               &req->elem.out_addr[1],
+                               req->elem.out_num - 1);
+    } else {
+        qemu_sgl_init_external(req, &req->elem.in_sg[1],
+                               &req->elem.in_addr[1],
+                               req->elem.in_num - 1);
+    }
+
+and this will access out of array bounds.
+
+Note: this adds security checks within assert calls since
+SCSIBusInfo's load_request cannot fail.
+For now simply disable builds with NDEBUG - there seems
+to be little value in supporting these.
+
+Cc: Andreas Färber <afaerber at suse.de>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 3c3ce981423e0d6c18af82ee62f1850c2cda5976)
+---
+ hw/scsi/virtio-scsi.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
+index b0d7517..1752193 100644
+--- a/hw/scsi/virtio-scsi.c
++++ b/hw/scsi/virtio-scsi.c
+@@ -147,6 +147,15 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
+     qemu_get_be32s(f, &n);
+     assert(n < vs->conf.num_queues);
+     qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
++    /* TODO: add a way for SCSIBusInfo's load_request to fail,
++     * and fail migration instead of asserting here.
++     * When we do, we might be able to re-enable NDEBUG below.
++     */
++#ifdef NDEBUG
++#error building with NDEBUG is not supported
++#endif
++    assert(req->elem.in_num <= ARRAY_SIZE(req->elem.in_sg));
++    assert(req->elem.out_num <= ARRAY_SIZE(req->elem.out_sg));
+     virtio_scsi_parse_req(s, vs->cmd_vqs[n], req);
+ 
+     scsi_req_ref(sreq);
diff --git a/0019-vmstate-s-VMSTATE_INT32_LE-VMSTATE_INT32_POSITIVE_LE.patch b/0019-vmstate-s-VMSTATE_INT32_LE-VMSTATE_INT32_POSITIVE_LE.patch
new file mode 100644
index 0000000..8b93785
--- /dev/null
+++ b/0019-vmstate-s-VMSTATE_INT32_LE-VMSTATE_INT32_POSITIVE_LE.patch
@@ -0,0 +1,65 @@
+From 83bb87c00e9970a1771ddcad3fd99091f5b2719c Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:52:21 +0300
+Subject: [PATCH] vmstate: s/VMSTATE_INT32_LE/VMSTATE_INT32_POSITIVE_LE/
+
+As the macro verifies the value is positive, rename it
+to make the function clearer.
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 3476436a44c29725efef0cabf5b3ea4e70054d57)
+---
+ hw/pci/pci.c                | 4 ++--
+ include/migration/vmstate.h | 2 +-
+ target-arm/machine.c        | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/hw/pci/pci.c b/hw/pci/pci.c
+index 2a9f08e..517ff2a 100644
+--- a/hw/pci/pci.c
++++ b/hw/pci/pci.c
+@@ -475,7 +475,7 @@ const VMStateDescription vmstate_pci_device = {
+     .minimum_version_id = 1,
+     .minimum_version_id_old = 1,
+     .fields      = (VMStateField []) {
+-        VMSTATE_INT32_LE(version_id, PCIDevice),
++        VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
+         VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
+                                    vmstate_info_pci_config,
+                                    PCI_CONFIG_SPACE_SIZE),
+@@ -492,7 +492,7 @@ const VMStateDescription vmstate_pcie_device = {
+     .minimum_version_id = 1,
+     .minimum_version_id_old = 1,
+     .fields      = (VMStateField []) {
+-        VMSTATE_INT32_LE(version_id, PCIDevice),
++        VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
+         VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
+                                    vmstate_info_pci_config,
+                                    PCIE_CONFIG_SPACE_SIZE),
+diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
+index 5b71370..7e45048 100644
+--- a/include/migration/vmstate.h
++++ b/include/migration/vmstate.h
+@@ -601,7 +601,7 @@ extern const VMStateInfo vmstate_info_bitmap;
+ #define VMSTATE_UINT64_EQUAL(_f, _s)                                  \
+     VMSTATE_UINT64_EQUAL_V(_f, _s, 0)
+ 
+-#define VMSTATE_INT32_LE(_f, _s)                                   \
++#define VMSTATE_INT32_POSITIVE_LE(_f, _s)                             \
+     VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
+ 
+ #define VMSTATE_UINT8_TEST(_f, _s, _t)                               \
+diff --git a/target-arm/machine.c b/target-arm/machine.c
+index 7ced87a..5746ffd 100644
+--- a/target-arm/machine.c
++++ b/target-arm/machine.c
+@@ -246,7 +246,7 @@ const VMStateDescription vmstate_arm_cpu = {
+         /* The length-check must come before the arrays to avoid
+          * incoming data possibly overflowing the array.
+          */
+-        VMSTATE_INT32_LE(cpreg_vmstate_array_len, ARMCPU),
++        VMSTATE_INT32_POSITIVE_LE(cpreg_vmstate_array_len, ARMCPU),
+         VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU,
+                              cpreg_vmstate_array_len,
+                              0, vmstate_info_uint64, uint64_t),
diff --git a/0020-usb-sanity-check-setup_index-setup_len-in-post_load.patch b/0020-usb-sanity-check-setup_index-setup_len-in-post_load.patch
new file mode 100644
index 0000000..824140c
--- /dev/null
+++ b/0020-usb-sanity-check-setup_index-setup_len-in-post_load.patch
@@ -0,0 +1,38 @@
+From a608c9c4150820ec64f5f25f6ebe244906c015da Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Thu, 3 Apr 2014 19:52:25 +0300
+Subject: [PATCH] usb: sanity check setup_index+setup_len in post_load
+
+CVE-2013-4541
+
+s->setup_len and s->setup_index are fed into usb_packet_copy as
+size/offset into s->data_buf, it's possible for invalid state to exploit
+this to load arbitrary data.
+
+setup_len and setup_index should be checked to make sure
+they are not negative.
+
+Cc: Gerd Hoffmann <kraxel at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Reviewed-by: Gerd Hoffmann <kraxel at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 9f8e9895c504149d7048e9fc5eb5cbb34b16e49a)
+---
+ hw/usb/bus.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/usb/bus.c b/hw/usb/bus.c
+index fe70429..e48b19f 100644
+--- a/hw/usb/bus.c
++++ b/hw/usb/bus.c
+@@ -49,7 +49,9 @@ static int usb_device_post_load(void *opaque, int version_id)
+     } else {
+         dev->attached = 1;
+     }
+-    if (dev->setup_index >= sizeof(dev->data_buf) ||
++    if (dev->setup_index < 0 ||
++        dev->setup_len < 0 ||
++        dev->setup_index >= sizeof(dev->data_buf) ||
+         dev->setup_len >= sizeof(dev->data_buf)) {
+         return -EINVAL;
+     }
diff --git a/0021-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch b/0021-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch
new file mode 100644
index 0000000..ac1e790
--- /dev/null
+++ b/0021-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch
@@ -0,0 +1,41 @@
+From d2c50b94a808f06d778746aec63ce2cb4eb1222f Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Mon, 28 Apr 2014 16:08:14 +0300
+Subject: [PATCH] ssi-sd: fix buffer overrun on invalid state load
+
+CVE-2013-4537
+
+s->arglen is taken from wire and used as idx
+in ssi_sd_transfer().
+
+Validate it before access.
+
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit a9c380db3b8c6af19546a68145c8d1438a09c92b)
+---
+ hw/sd/ssi-sd.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
+index 3273c8a..b012e57 100644
+--- a/hw/sd/ssi-sd.c
++++ b/hw/sd/ssi-sd.c
+@@ -230,8 +230,17 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
+     for (i = 0; i < 5; i++)
+         s->response[i] = qemu_get_be32(f);
+     s->arglen = qemu_get_be32(f);
++    if (s->mode == SSI_SD_CMDARG &&
++        (s->arglen < 0 || s->arglen >= ARRAY_SIZE(s->cmdarg))) {
++        return -EINVAL;
++    }
+     s->response_pos = qemu_get_be32(f);
+     s->stopping = qemu_get_be32(f);
++    if (s->mode == SSI_SD_RESPONSE &&
++        (s->response_pos < 0 || s->response_pos >= ARRAY_SIZE(s->response) ||
++        (!s->stopping && s->arglen > ARRAY_SIZE(s->response)))) {
++        return -EINVAL;
++    }
+ 
+     ss->cs = qemu_get_be32(f);
+ 
diff --git a/0022-openpic-avoid-buffer-overrun-on-incoming-migration.patch b/0022-openpic-avoid-buffer-overrun-on-incoming-migration.patch
new file mode 100644
index 0000000..b9404dc
--- /dev/null
+++ b/0022-openpic-avoid-buffer-overrun-on-incoming-migration.patch
@@ -0,0 +1,72 @@
+From 70488d5f1746b720bc141ea6b9850585e9c42121 Mon Sep 17 00:00:00 2001
+From: Michael Roth <mdroth at linux.vnet.ibm.com>
+Date: Mon, 28 Apr 2014 16:08:17 +0300
+Subject: [PATCH] openpic: avoid buffer overrun on incoming migration
+
+CVE-2013-4534
+
+opp->nb_cpus is read from the wire and used to determine how many
+IRQDest elements to read into opp->dst[]. If the value exceeds the
+length of opp->dst[], MAX_CPU, opp->dst[] can be overrun with arbitrary
+data from the wire.
+
+Fix this by failing migration if the value read from the wire exceeds
+MAX_CPU.
+
+Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Reviewed-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 73d963c0a75cb99c6aaa3f6f25e427aa0b35a02e)
+---
+ hw/intc/openpic.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
+index be76fbd..17136c9 100644
+--- a/hw/intc/openpic.c
++++ b/hw/intc/openpic.c
+@@ -41,6 +41,7 @@
+ #include "hw/sysbus.h"
+ #include "hw/pci/msi.h"
+ #include "qemu/bitops.h"
++#include "qapi/qmp/qerror.h"
+ 
+ //#define DEBUG_OPENPIC
+ 
+@@ -1416,7 +1417,7 @@ static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
+ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
+ {
+     OpenPICState *opp = (OpenPICState *)opaque;
+-    unsigned int i;
++    unsigned int i, nb_cpus;
+ 
+     if (version_id != 1) {
+         return -EINVAL;
+@@ -1428,7 +1429,11 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
+     qemu_get_be32s(f, &opp->spve);
+     qemu_get_be32s(f, &opp->tfrr);
+ 
+-    qemu_get_be32s(f, &opp->nb_cpus);
++    qemu_get_be32s(f, &nb_cpus);
++    if (opp->nb_cpus != nb_cpus) {
++        return -EINVAL;
++    }
++    assert(nb_cpus > 0 && nb_cpus <= MAX_CPU);
+ 
+     for (i = 0; i < opp->nb_cpus; i++) {
+         qemu_get_sbe32s(f, &opp->dst[i].ctpr);
+@@ -1567,6 +1572,13 @@ static void openpic_realize(DeviceState *dev, Error **errp)
+         {NULL}
+     };
+ 
++    if (opp->nb_cpus > MAX_CPU) {
++        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
++                  TYPE_OPENPIC, "nb_cpus", (uint64_t)opp->nb_cpus,
++                  (uint64_t)0, (uint64_t)MAX_CPU);
++        return;
++    }
++
+     switch (opp->model) {
+     case OPENPIC_MODEL_FSL_MPIC_20:
+     default:
diff --git a/0023-virtio-net-out-of-bounds-buffer-write-on-load.patch b/0023-virtio-net-out-of-bounds-buffer-write-on-load.patch
new file mode 100644
index 0000000..cf100f3
--- /dev/null
+++ b/0023-virtio-net-out-of-bounds-buffer-write-on-load.patch
@@ -0,0 +1,55 @@
+From 1a29e58f9f23846d0e105a3157629786fc624f65 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Mon, 28 Apr 2014 16:08:21 +0300
+Subject: [PATCH] virtio-net: out-of-bounds buffer write on load
+
+CVE-2013-4149 QEMU 1.3.0 out-of-bounds buffer write in
+virtio_net_load()@hw/net/virtio-net.c
+
+>         } else if (n->mac_table.in_use) {
+>             uint8_t *buf = g_malloc0(n->mac_table.in_use);
+
+We are allocating buffer of size n->mac_table.in_use
+
+>             qemu_get_buffer(f, buf, n->mac_table.in_use * ETH_ALEN);
+
+and read to the n->mac_table.in_use size buffer n->mac_table.in_use *
+ETH_ALEN bytes, corrupting memory.
+
+If adversary controls state then memory written there is controlled
+by adversary.
+
+Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit 98f93ddd84800f207889491e0b5d851386b459cf)
+---
+ hw/net/virtio-net.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
+index 0a8cb40..940a7cf 100644
+--- a/hw/net/virtio-net.c
++++ b/hw/net/virtio-net.c
+@@ -1362,10 +1362,17 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
+         if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
+             qemu_get_buffer(f, n->mac_table.macs,
+                             n->mac_table.in_use * ETH_ALEN);
+-        } else if (n->mac_table.in_use) {
+-            uint8_t *buf = g_malloc0(n->mac_table.in_use);
+-            qemu_get_buffer(f, buf, n->mac_table.in_use * ETH_ALEN);
+-            g_free(buf);
++        } else {
++            int64_t i;
++
++            /* Overflow detected - can happen if source has a larger MAC table.
++             * We simply set overflow flag so there's no need to maintain the
++             * table of addresses, discard them all.
++             * Note: 64 bit math to avoid integer overflow.
++             */
++            for (i = 0; i < (int64_t)n->mac_table.in_use * ETH_ALEN; ++i) {
++                qemu_get_byte(f);
++            }
+             n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
+             n->mac_table.in_use = 0;
+         }
diff --git a/0024-virtio-validate-config_len-on-load.patch b/0024-virtio-validate-config_len-on-load.patch
new file mode 100644
index 0000000..9e6dde4
--- /dev/null
+++ b/0024-virtio-validate-config_len-on-load.patch
@@ -0,0 +1,52 @@
+From 94998eaa5ef06ba17ad12976ac84801033a28582 Mon Sep 17 00:00:00 2001
+From: "Michael S. Tsirkin" <mst at redhat.com>
+Date: Mon, 28 Apr 2014 16:08:23 +0300
+Subject: [PATCH] virtio: validate config_len on load
+
+Malformed input can have config_len in migration stream
+exceed the array size allocated on destination, the
+result will be heap overflow.
+
+To fix, that config_len matches on both sides.
+
+CVE-2014-0182
+
+Reported-by: "Dr. David Alan Gilbert" <dgilbert at redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+
+--
+
+v2: use %ix and %zx to print config_len values
+Signed-off-by: Juan Quintela <quintela at redhat.com>
+(cherry picked from commit a890a2f9137ac3cf5b607649e66a6f3a5512d8dc)
+---
+ hw/virtio/virtio.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
+index a70169a..7f4e7ec 100644
+--- a/hw/virtio/virtio.c
++++ b/hw/virtio/virtio.c
+@@ -898,6 +898,7 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val)
+ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
+ {
+     int i, ret;
++    int32_t config_len;
+     uint32_t num;
+     uint32_t features;
+     uint32_t supported_features;
+@@ -924,7 +925,12 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
+                      features, supported_features);
+         return -1;
+     }
+-    vdev->config_len = qemu_get_be32(f);
++    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;
++    }
+     qemu_get_buffer(f, vdev->config, vdev->config_len);
+ 
+     num = qemu_get_be32(f);
diff --git a/qemu.spec b/qemu.spec
index 7d335d8..17ede15 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -158,7 +158,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 2.0.0
-Release: 3%{?dist}
+Release: 4%{?dist}
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
 Group: Development/Tools
@@ -201,6 +201,30 @@ Source13: qemu-kvm.sh
 # Change gtk quit accelerator to ctrl+shift+q (bz #1062393)
 # Patches queued for 2.1
 Patch0001: 0001-Change-gtk-quit-accelerator-to-ctrl-shift-q-bz-10623.patch
+# Migration CVEs: CVE-2014-0182 etc.
+Patch0002: 0002-vmstate-add-VMS_MUST_EXIST.patch
+Patch0003: 0003-vmstate-add-VMSTATE_VALIDATE.patch
+Patch0004: 0004-virtio-net-fix-buffer-overflow-on-invalid-state-load.patch
+Patch0005: 0005-virtio-net-out-of-bounds-buffer-write-on-invalid-sta.patch
+Patch0006: 0006-virtio-out-of-bounds-buffer-write-on-invalid-state-l.patch
+Patch0007: 0007-ahci-fix-buffer-overrun-on-invalid-state-load.patch
+Patch0008: 0008-hpet-fix-buffer-overrun-on-invalid-state-load.patch
+Patch0009: 0009-hw-pci-pcie_aer.c-fix-buffer-overruns-on-invalid-sta.patch
+Patch0010: 0010-pl022-fix-buffer-overun-on-invalid-state-load.patch
+Patch0011: 0011-vmstate-fix-buffer-overflow-in-target-arm-machine.c.patch
+Patch0012: 0012-virtio-avoid-buffer-overrun-on-incoming-migration.patch
+Patch0013: 0013-virtio-validate-num_sg-when-mapping.patch
+Patch0014: 0014-pxa2xx-avoid-buffer-overrun-on-incoming-migration.patch
+Patch0015: 0015-ssd0323-fix-buffer-overun-on-invalid-state-load.patch
+Patch0016: 0016-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch
+Patch0017: 0017-zaurus-fix-buffer-overrun-on-invalid-state-load.patch
+Patch0018: 0018-virtio-scsi-fix-buffer-overrun-on-invalid-state-load.patch
+Patch0019: 0019-vmstate-s-VMSTATE_INT32_LE-VMSTATE_INT32_POSITIVE_LE.patch
+Patch0020: 0020-usb-sanity-check-setup_index-setup_len-in-post_load.patch
+Patch0021: 0021-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch
+Patch0022: 0022-openpic-avoid-buffer-overrun-on-incoming-migration.patch
+Patch0023: 0023-virtio-net-out-of-bounds-buffer-write-on-load.patch
+Patch0024: 0024-virtio-validate-config_len-on-load.patch
 
 BuildRequires: SDL-devel
 BuildRequires: zlib-devel
@@ -726,6 +750,30 @@ CAC emulation development files.
 # Change gtk quit accelerator to ctrl+shift+q (bz #1062393)
 # Patches queued for 2.1
 %patch0001 -p1
+# Migration CVEs: CVE-2014-0182 etc.
+%patch0002 -p1
+%patch0003 -p1
+%patch0004 -p1
+%patch0005 -p1
+%patch0006 -p1
+%patch0007 -p1
+%patch0008 -p1
+%patch0009 -p1
+%patch0010 -p1
+%patch0011 -p1
+%patch0012 -p1
+%patch0013 -p1
+%patch0014 -p1
+%patch0015 -p1
+%patch0016 -p1
+%patch0017 -p1
+%patch0018 -p1
+%patch0019 -p1
+%patch0020 -p1
+%patch0021 -p1
+%patch0022 -p1
+%patch0023 -p1
+%patch0024 -p1
 
 
 %build
@@ -1493,6 +1541,9 @@ getent passwd qemu >/dev/null || \
 %endif
 
 %changelog
+* Sun May 11 2014 Cole Robinson <crobinso at redhat.com> - 2:2.0.0-4
+- Migration CVEs: CVE-2014-0182 etc.
+
 * Wed Apr 30 2014 Peter Robinson <pbrobinson at fedoraproject.org> 2:2.0.0-3
 - Fix aarch64 build
 


More information about the scm-commits mailing list