svn commit: r390664 - in head/emulators: qemu qemu-devel qemu-devel/files qemu-sbruno qemu-sbruno/files qemu/files

Juergen Lock nox at FreeBSD.org
Fri Jun 26 19:14:43 UTC 2015


Author: nox
Date: Fri Jun 26 19:14:41 2015
New Revision: 390664
URL: https://svnweb.freebsd.org/changeset/ports/390664

Log:
  - Apply fixes for pcnet guest to host escape vulnerability - CVE-2015-3209.
  - Bump PORTREVISIONs.
  
  PR:		201064
  Submitted by:	koobs
  Security:	https://vuxml.FreeBSD.org/freebsd/acd5d037-1c33-11e5-be9c-6805ca
  1d3bb1.html

Added:
  head/emulators/qemu-devel/files/patch-CVE-2015-3209   (contents, props changed)
  head/emulators/qemu-sbruno/files/patch-CVE-2015-3209   (contents, props changed)
  head/emulators/qemu/files/patch-CVE-2015-3209   (contents, props changed)
Modified:
  head/emulators/qemu-devel/Makefile
  head/emulators/qemu-sbruno/Makefile
  head/emulators/qemu/Makefile

Modified: head/emulators/qemu-devel/Makefile
==============================================================================
--- head/emulators/qemu-devel/Makefile	Fri Jun 26 19:13:31 2015	(r390663)
+++ head/emulators/qemu-devel/Makefile	Fri Jun 26 19:14:41 2015	(r390664)
@@ -3,7 +3,7 @@
 
 PORTNAME=	qemu
 PORTVERSION=	2.3.0
-PORTREVISION=	1
+PORTREVISION=	2
 CATEGORIES=	emulators
 MASTER_SITES=	http://wiki.qemu.org/download/:release \
 		LOCAL/nox:snapshot

Added: head/emulators/qemu-devel/files/patch-CVE-2015-3209
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/emulators/qemu-devel/files/patch-CVE-2015-3209	Fri Jun 26 19:14:41 2015	(r390664)
@@ -0,0 +1,45 @@
+From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001
+From: Petr Matousek <pmatouse at redhat.com>
+Date: Sun, 24 May 2015 10:53:44 +0200
+Subject: [PATCH] pcnet: force the buffer access to be in bounds during tx
+
+4096 is the maximum length per TMD and it is also currently the size of
+the relay buffer pcnet driver uses for sending the packet data to QEMU
+for further processing. With packet spanning multiple TMDs it can
+happen that the overall packet size will be bigger than sizeof(buffer),
+which results in memory corruption.
+
+Fix this by only allowing to queue maximum sizeof(buffer) bytes.
+
+This is CVE-2015-3209.
+
+Signed-off-by: Petr Matousek <pmatouse at redhat.com>
+Reported-by: Matt Tait <matttait at google.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
+---
+ hw/net/pcnet.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
+index bdfd38f..6d32e4c 100644
+--- a/hw/net/pcnet.c
++++ b/hw/net/pcnet.c
+@@ -1241,6 +1241,14 @@ static void pcnet_transmit(PCNetState *s)
+         }
+
+         bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
++
++        /* if multi-tmd packet outsizes s->buffer then skip it silently.
++           Note: this is not what real hw does */
++        if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
++           s->xmit_pos = -1;
++           goto txdone;
++        }
++
+         s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+                          s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+         s->xmit_pos += bcnt;
+-- 
+2.1.0
+

Modified: head/emulators/qemu-sbruno/Makefile
==============================================================================
--- head/emulators/qemu-sbruno/Makefile	Fri Jun 26 19:13:31 2015	(r390663)
+++ head/emulators/qemu-sbruno/Makefile	Fri Jun 26 19:14:41 2015	(r390664)
@@ -3,6 +3,7 @@
 
 PORTNAME=	qemu
 PORTVERSION=	2.3.50.g20150618
+PORTREVISION=	1
 CATEGORIES=	emulators
 MASTER_SITES=	GH \
 		LOCAL/nox \

Added: head/emulators/qemu-sbruno/files/patch-CVE-2015-3209
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/emulators/qemu-sbruno/files/patch-CVE-2015-3209	Fri Jun 26 19:14:41 2015	(r390664)
@@ -0,0 +1,45 @@
+From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001
+From: Petr Matousek <pmatouse at redhat.com>
+Date: Sun, 24 May 2015 10:53:44 +0200
+Subject: [PATCH] pcnet: force the buffer access to be in bounds during tx
+
+4096 is the maximum length per TMD and it is also currently the size of
+the relay buffer pcnet driver uses for sending the packet data to QEMU
+for further processing. With packet spanning multiple TMDs it can
+happen that the overall packet size will be bigger than sizeof(buffer),
+which results in memory corruption.
+
+Fix this by only allowing to queue maximum sizeof(buffer) bytes.
+
+This is CVE-2015-3209.
+
+Signed-off-by: Petr Matousek <pmatouse at redhat.com>
+Reported-by: Matt Tait <matttait at google.com>
+Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
+Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
+---
+ hw/net/pcnet.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
+index bdfd38f..6d32e4c 100644
+--- a/hw/net/pcnet.c
++++ b/hw/net/pcnet.c
+@@ -1241,6 +1241,14 @@ static void pcnet_transmit(PCNetState *s)
+         }
+
+         bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
++
++        /* if multi-tmd packet outsizes s->buffer then skip it silently.
++           Note: this is not what real hw does */
++        if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
++           s->xmit_pos = -1;
++           goto txdone;
++        }
++
+         s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+                          s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+         s->xmit_pos += bcnt;
+-- 
+2.1.0
+

Modified: head/emulators/qemu/Makefile
==============================================================================
--- head/emulators/qemu/Makefile	Fri Jun 26 19:13:31 2015	(r390663)
+++ head/emulators/qemu/Makefile	Fri Jun 26 19:14:41 2015	(r390664)
@@ -3,7 +3,7 @@
 
 PORTNAME=	qemu
 PORTVERSION=	0.11.1
-PORTREVISION=	19
+PORTREVISION=	20
 CATEGORIES=	emulators
 MASTER_SITES=	SAVANNAH \
 		http://bellard.org/qemu/

Added: head/emulators/qemu/files/patch-CVE-2015-3209
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/emulators/qemu/files/patch-CVE-2015-3209	Fri Jun 26 19:14:41 2015	(r390664)
@@ -0,0 +1,82 @@
+--- a/hw/pcnet.c
++++ b/hw/pcnet.c
+@@ -1263,7 +1263,7 @@ static void pcnet_transmit(PCNetState *s
+     target_phys_addr_t xmit_cxda = 0;
+     int count = CSR_XMTRL(s)-1;
+     int add_crc = 0;
+-
++    int bcnt;
+     s->xmit_pos = -1;
+ 
+     if (!CSR_TXON(s)) {
+@@ -1289,34 +1289,47 @@ static void pcnet_transmit(PCNetState *s
+             if (BCR_SWSTYLE(s) != 1)
+                 add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
+         }
++
++        if (s->xmit_pos < 0) {
++            goto txdone;
++        }
++
++        bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
++
++        /* if multi-tmd packet outsizes s->buffer then skip it silently.
++           Note: this is not what real hw does */
++        if (s->xmit_pos + bcnt > sizeof(s->buffer)) {
++           s->xmit_pos = -1;
++           goto txdone;
++        }
++
++        s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
++                         s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
++        s->xmit_pos += bcnt;
++        
+         if (!GET_FIELD(tmd.status, TMDS, ENP)) {
+-            int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
+-            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+-                             s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+-            s->xmit_pos += bcnt;
+-        } else if (s->xmit_pos >= 0) {
+-            int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
+-            s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+-                             s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+-            s->xmit_pos += bcnt;
++            goto txdone;
++        }
+ #ifdef PCNET_DEBUG
+-            printf("pcnet_transmit size=%d\n", s->xmit_pos);
++        printf("pcnet_transmit size=%d\n", s->xmit_pos);
+ #endif
+-            if (CSR_LOOP(s)) {
+-                if (BCR_SWSTYLE(s) == 1)
+-                    add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
+-                s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
+-                pcnet_receive(s->vc, s->buffer, s->xmit_pos);
+-                s->looptest = 0;
+-            } else
+-                if (s->vc)
+-                    qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
+-
+-            s->csr[0] &= ~0x0008;   /* clear TDMD */
+-            s->csr[4] |= 0x0004;    /* set TXSTRT */
+-            s->xmit_pos = -1;
++        if (CSR_LOOP(s)) {
++            if (BCR_SWSTYLE(s) == 1)
++                add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
++            s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
++            pcnet_receive(s->vc, s->buffer, s->xmit_pos);
++            s->looptest = 0;
++        } else {
++            if (s->vc) {
++                qemu_send_packet(s->vc, s->buffer, s->xmit_pos);
++            }
+         }
+ 
++        s->csr[0] &= ~0x0008;   /* clear TDMD */
++        s->csr[4] |= 0x0004;    /* set TXSTRT */
++        s->xmit_pos = -1;
++
++     txdone:
+         SET_FIELD(&tmd.status, TMDS, OWN, 0);
+         TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
+         if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))


More information about the svn-ports-head mailing list