yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/kvm-virtio-net-out-of-bounds-buffer-write-on-invalid-sta.patch

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