peterdelevoryas / rpms / qemu

Forked from rpms/qemu 2 years ago
Clone

Blame 0005-virtio-net-out-of-bounds-buffer-write-on-invalid-sta.patch

70114f
From 9229c44bfa3549085ac68265d9be95a8552c4fa4 Mon Sep 17 00:00:00 2001
70114f
From: "Michael S. Tsirkin" <mst@redhat.com>
70114f
Date: Thu, 3 Apr 2014 19:50:56 +0300
70114f
Subject: [PATCH] virtio-net: out-of-bounds buffer write on invalid state load
70114f
70114f
CVE-2013-4150 QEMU 1.5.0 out-of-bounds buffer write in
70114f
virtio_net_load()@hw/net/virtio-net.c
70114f
70114f
This code is in hw/net/virtio-net.c:
70114f
70114f
    if (n->max_queues > 1) {
70114f
        if (n->max_queues != qemu_get_be16(f)) {
70114f
            error_report("virtio-net: different max_queues ");
70114f
            return -1;
70114f
        }
70114f
70114f
        n->curr_queues = qemu_get_be16(f);
70114f
        for (i = 1; i < n->curr_queues; i++) {
70114f
            n->vqs[i].tx_waiting = qemu_get_be32(f);
70114f
        }
70114f
    }
70114f
70114f
Number of vqs is max_queues, so if we get invalid input here,
70114f
for example if max_queues = 2, curr_queues = 3, we get
70114f
write beyond end of the buffer, with data that comes from
70114f
wire.
70114f
70114f
This might be used to corrupt qemu memory in hard to predict ways.
70114f
Since we have lots of function pointers around, RCE might be possible.
70114f
70114f
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
70114f
Acked-by: Jason Wang <jasowang@redhat.com>
70114f
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
70114f
Signed-off-by: Juan Quintela <quintela@redhat.com>
70114f
(cherry picked from commit eea750a5623ddac7a61982eec8f1c93481857578)
70114f
---
70114f
 hw/net/virtio-net.c | 5 +++++
70114f
 1 file changed, 5 insertions(+)
70114f
70114f
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
70114f
index 33bd233..0a8cb40 100644
70114f
--- a/hw/net/virtio-net.c
70114f
+++ b/hw/net/virtio-net.c
70114f
@@ -1407,6 +1407,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
70114f
         }
70114f
 
70114f
         n->curr_queues = qemu_get_be16(f);
70114f
+        if (n->curr_queues > n->max_queues) {
70114f
+            error_report("virtio-net: curr_queues %x > max_queues %x",
70114f
+                         n->curr_queues, n->max_queues);
70114f
+            return -1;
70114f
+        }
70114f
         for (i = 1; i < n->curr_queues; i++) {
70114f
             n->vqs[i].tx_waiting = qemu_get_be32(f);
70114f
         }