yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
9ae3a8
From 953a3b8344e504a7333ba9bb6df840d6d94ff872 Mon Sep 17 00:00:00 2001
9ae3a8
From: Michael S. Tsirkin <mst@redhat.com>
9ae3a8
Date: Wed, 14 May 2014 08:31:47 +0200
9ae3a8
Subject: [PATCH 10/31] virtio-net: out-of-bounds buffer write on invalid state load
9ae3a8
9ae3a8
RH-Author: Michael S. Tsirkin <mst@redhat.com>
9ae3a8
Message-id: <1400056285-6688-3-git-send-email-mst@redhat.com>
9ae3a8
Patchwork-id: 58857
9ae3a8
O-Subject: [PATCH qemu-kvm RHEL7.1] virtio-net: out-of-bounds buffer write on invalid state load
9ae3a8
Bugzilla: 1095690
9ae3a8
RH-Acked-by: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
9ae3a8
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
9ae3a8
RH-Acked-by: Juan Quintela <quintela@redhat.com>
9ae3a8
9ae3a8
CVE-2013-4150 QEMU 1.5.0 out-of-bounds buffer write in
9ae3a8
virtio_net_load()@hw/net/virtio-net.c
9ae3a8
9ae3a8
This code is in hw/net/virtio-net.c:
9ae3a8
9ae3a8
    if (n->max_queues > 1) {
9ae3a8
        if (n->max_queues != qemu_get_be16(f)) {
9ae3a8
            error_report("virtio-net: different max_queues ");
9ae3a8
            return -1;
9ae3a8
        }
9ae3a8
9ae3a8
        n->curr_queues = qemu_get_be16(f);
9ae3a8
        for (i = 1; i < n->curr_queues; i++) {
9ae3a8
            n->vqs[i].tx_waiting = qemu_get_be32(f);
9ae3a8
        }
9ae3a8
    }
9ae3a8
9ae3a8
Number of vqs is max_queues, so if we get invalid input here,
9ae3a8
for example if max_queues = 2, curr_queues = 3, we get
9ae3a8
write beyond end of the buffer, with data that comes from
9ae3a8
wire.
9ae3a8
9ae3a8
This might be used to corrupt qemu memory in hard to predict ways.
9ae3a8
Since we have lots of function pointers around, RCE might be possible.
9ae3a8
9ae3a8
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
9ae3a8
Acked-by: Jason Wang <jasowang@redhat.com>
9ae3a8
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
9ae3a8
Signed-off-by: Juan Quintela <quintela@redhat.com>
9ae3a8
(cherry picked from commit eea750a5623ddac7a61982eec8f1c93481857578)
9ae3a8
9ae3a8
Tested: lightly on developer's box
9ae3a8
Brew build: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7452039
9ae3a8
Bugzilla: 1095690
9ae3a8
---
9ae3a8
 hw/net/virtio-net.c | 5 +++++
9ae3a8
 1 file changed, 5 insertions(+)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/net/virtio-net.c |    5 +++++
9ae3a8
 1 files changed, 5 insertions(+), 0 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
9ae3a8
index 2d559e0..007cc2a 100644
9ae3a8
--- a/hw/net/virtio-net.c
9ae3a8
+++ b/hw/net/virtio-net.c
9ae3a8
@@ -1327,6 +1327,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
9ae3a8
         }
9ae3a8
 
9ae3a8
         n->curr_queues = qemu_get_be16(f);
9ae3a8
+        if (n->curr_queues > n->max_queues) {
9ae3a8
+            error_report("virtio-net: curr_queues %x > max_queues %x",
9ae3a8
+                         n->curr_queues, n->max_queues);
9ae3a8
+            return -1;
9ae3a8
+        }
9ae3a8
         for (i = 1; i < n->curr_queues; i++) {
9ae3a8
             n->vqs[i].tx_waiting = qemu_get_be32(f);
9ae3a8
         }
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8