diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2014-04-03 19:50:39 +0300 |
---|---|---|
committer | Juan Quintela <quintela@redhat.com> | 2014-05-05 14:15:10 +0200 |
commit | 71f7fe48e10a8437c9d42d859389f37157f59980 (patch) | |
tree | 6984fa70c53fefbaa28af8e12f8456300e92f5a9 /include | |
parent | 4082f0889ba04678fc14816c53e1b9251ea9207e (diff) | |
download | hqemu-71f7fe48e10a8437c9d42d859389f37157f59980.zip hqemu-71f7fe48e10a8437c9d42d859389f37157f59980.tar.gz |
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@linux.vnet.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/hw/virtio/virtio-net.h | 4 |
1 files 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; |