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