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

eb5a2f
From 2b6768100640ef4b0387f42391f5e9e82cf67284 Mon Sep 17 00:00:00 2001
eb5a2f
From: Michael S. Tsirkin <mst@redhat.com>
eb5a2f
Date: Wed, 14 May 2014 08:07:45 +0200
eb5a2f
Subject: [PATCH 03/30] virtio-net: out-of-bounds buffer write on invalid state load
eb5a2f
eb5a2f
RH-Author: Michael S. Tsirkin <mst@redhat.com>
eb5a2f
Message-id: <1400054498-4366-3-git-send-email-mst@redhat.com>
eb5a2f
Patchwork-id: 58841
eb5a2f
O-Subject: [PATCH qemu-kvm RHEL7.0] virtio-net: out-of-bounds buffer write on invalid state load
eb5a2f
Bugzilla: 1095689
eb5a2f
RH-Acked-by: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
eb5a2f
RH-Acked-by: Juan Quintela <quintela@redhat.com>
eb5a2f
RH-Acked-by: Vlad Yasevich <vyasevic@redhat.com>
eb5a2f
RH-Acked-by: Xiao Wang <jasowang@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
eb5a2f
Brew build: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7450401
eb5a2f
Bugzilla: 1095689
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
eb5a2f
index f6ed241..f72be9f 100644
eb5a2f
--- a/hw/net/virtio-net.c
eb5a2f
+++ b/hw/net/virtio-net.c
eb5a2f
@@ -1334,6 +1334,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