From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42084) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VnsnQ-0006Mz-Nj for qemu-devel@nongnu.org; Tue, 03 Dec 2013 11:26:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VnsnK-0006td-Oc for qemu-devel@nongnu.org; Tue, 03 Dec 2013 11:26:00 -0500 Date: Tue, 3 Dec 2013 18:28:51 +0200 From: "Michael S. Tsirkin" Message-ID: <1386087086-3691-12-git-send-email-mst@redhat.com> References: <1386087086-3691-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1386087086-3691-1-git-send-email-mst@redhat.com> Subject: [Qemu-devel] [PATCH 11/23] stellaris_enet: avoid buffer overrun on incoming migration (part 2) List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , qemu-stable@nongnu.org, Michael Roth From: Michael Roth CVE-2013-4532 s->tx_fifo_len is read from the wire and later used as an index into s->tx_fifo[] when a DATA command is issued by the guest. If s->tx_fifo_len is greater than the length of s->tx_fifo[], or less than 0, the buffer can be overrun/underrun by arbitrary data written out by the guest upon resuming it's execution. Fix this by introducing a constant that defines the length of s->tx_fifo[] and failing migration if the value from the wire exceeds this, or is less than 0. Signed-off-by: Michael Roth Signed-off-by: Michael S. Tsirkin --- hw/net/stellaris_enet.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c index db12a99..65f0ba8 100644 --- a/hw/net/stellaris_enet.c +++ b/hw/net/stellaris_enet.c @@ -63,10 +63,11 @@ typedef struct { int tx_fifo_len; /* Real hardware has a 2k fifo, which works out to be at most 31 packets. We implement a full 31 packet fifo. */ - uint8_t tx_fifo[2048]; +#define SE_FIFO_LEN 2048 + uint8_t tx_fifo[SE_FIFO_LEN]; #define SE_RX_BUF_LEN 31 struct { - uint8_t data[2048]; + uint8_t data[SE_FIFO_LEN]; int len; } rx[SE_RX_BUF_LEN]; uint8_t *rx_fifo; @@ -375,6 +376,9 @@ static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id) s->np = qemu_get_be32(f); s->tx_frame_len = qemu_get_be32(f); s->tx_fifo_len = qemu_get_be32(f); + if (s->tx_fifo_len < 0 || s->tx_fifo_len > SE_FIFO_LEN) { + return -EINVAL; + } qemu_get_buffer(f, s->tx_fifo, sizeof(s->tx_fifo)); for (i = 0; i < SE_RX_BUF_LEN; i++) { s->rx[i].len = qemu_get_be32(f); -- MST