From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41332) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WUd0R-0007po-Mq for qemu-devel@nongnu.org; Mon, 31 Mar 2014 10:16:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WUd0L-0000SQ-IM for qemu-devel@nongnu.org; Mon, 31 Mar 2014 10:16:07 -0400 Date: Mon, 31 Mar 2014 17:16:24 +0300 From: "Michael S. Tsirkin" Message-ID: <1396275242-10810-7-git-send-email-mst@redhat.com> References: <1396275242-10810-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1396275242-10810-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PATCH v4 06/30] 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: Jason Wang , qemu-stable@nongnu.org, dgilbert@redhat.com, Anthony Liguori , mdroth@linux.vnet.ibm.com 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 8d037b1..c811fbd 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