From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47692) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WVkro-0006cH-NW for qemu-devel@nongnu.org; Thu, 03 Apr 2014 12:52:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WVkrg-0005nd-QM for qemu-devel@nongnu.org; Thu, 03 Apr 2014 12:51:52 -0400 Date: Thu, 3 Apr 2014 19:50:56 +0300 From: "Michael S. Tsirkin" Message-ID: <1396543778-22307-7-git-send-email-mst@redhat.com> References: <1396543778-22307-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1396543778-22307-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PATCH v5 06/24] virtio-net: out-of-bounds buffer write on invalid state load List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , mdroth@linux.vnet.ibm.com, Jason Wang , qemu-stable@nongnu.org, dgilbert@redhat.com, Anthony Liguori CVE-2013-4150 QEMU 1.5.0 out-of-bounds buffer write in virtio_net_load()@hw/net/virtio-net.c This code is in hw/net/virtio-net.c: if (n->max_queues > 1) { if (n->max_queues != qemu_get_be16(f)) { error_report("virtio-net: different max_queues "); return -1; } n->curr_queues = qemu_get_be16(f); for (i = 1; i < n->curr_queues; i++) { n->vqs[i].tx_waiting = qemu_get_be32(f); } } Number of vqs is max_queues, so if we get invalid input here, for example if max_queues = 2, curr_queues = 3, we get write beyond end of the buffer, with data that comes from wire. This might be used to corrupt qemu memory in hard to predict ways. Since we have lots of function pointers around, RCE might be possible. Signed-off-by: Michael S. Tsirkin Acked-by: Jason Wang Reviewed-by: Michael Roth --- hw/net/virtio-net.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index c247529..2a702e3 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1413,6 +1413,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) } n->curr_queues = qemu_get_be16(f); + if (n->curr_queues > n->max_queues) { + error_report("virtio-net: curr_queues %x > max_queues %x", + n->curr_queues, n->max_queues); + return -1; + } for (i = 1; i < n->curr_queues; i++) { n->vqs[i].tx_waiting = qemu_get_be32(f); } -- MST