aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornox <nox@FreeBSD.org>2015-06-27 03:14:41 +0800
committernox <nox@FreeBSD.org>2015-06-27 03:14:41 +0800
commit7160e4b0022ce7487fc1d1aa3a6dfdbd5c83e2aa (patch)
treead5cdc338b859b6160567370a1aa78c048944383
parente8387a7717e75c1f4bd1b9592c841b98fb6cf17a (diff)
downloadfreebsd-ports-gnome-7160e4b0022ce7487fc1d1aa3a6dfdbd5c83e2aa.tar.gz
freebsd-ports-gnome-7160e4b0022ce7487fc1d1aa3a6dfdbd5c83e2aa.tar.zst
freebsd-ports-gnome-7160e4b0022ce7487fc1d1aa3a6dfdbd5c83e2aa.zip
- 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
-rw-r--r--emulators/qemu-devel/Makefile2
-rw-r--r--emulators/qemu-devel/files/patch-CVE-2015-320945
-rw-r--r--emulators/qemu-sbruno/Makefile1
-rw-r--r--emulators/qemu-sbruno/files/patch-CVE-2015-320945
-rw-r--r--emulators/qemu/Makefile2
-rw-r--r--emulators/qemu/files/patch-CVE-2015-320982
6 files changed, 175 insertions, 2 deletions
diff --git a/emulators/qemu-devel/Makefile b/emulators/qemu-devel/Makefile
index af7e737b63ae..7148bb0b2a39 100644
--- a/emulators/qemu-devel/Makefile
+++ b/emulators/qemu-devel/Makefile
@@ -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
diff --git a/emulators/qemu-devel/files/patch-CVE-2015-3209 b/emulators/qemu-devel/files/patch-CVE-2015-3209
new file mode 100644
index 000000000000..4fe7df5440fd
--- /dev/null
+++ b/emulators/qemu-devel/files/patch-CVE-2015-3209
@@ -0,0 +1,45 @@
+From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001
+From: Petr Matousek <pmatouse@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@redhat.com>
+Reported-by: Matt Tait <matttait@google.com>
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@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
+
diff --git a/emulators/qemu-sbruno/Makefile b/emulators/qemu-sbruno/Makefile
index d7705c39983d..cd1ccb1db2b1 100644
--- a/emulators/qemu-sbruno/Makefile
+++ b/emulators/qemu-sbruno/Makefile
@@ -3,6 +3,7 @@
PORTNAME= qemu
PORTVERSION= 2.3.50.g20150618
+PORTREVISION= 1
CATEGORIES= emulators
MASTER_SITES= GH \
LOCAL/nox \
diff --git a/emulators/qemu-sbruno/files/patch-CVE-2015-3209 b/emulators/qemu-sbruno/files/patch-CVE-2015-3209
new file mode 100644
index 000000000000..4fe7df5440fd
--- /dev/null
+++ b/emulators/qemu-sbruno/files/patch-CVE-2015-3209
@@ -0,0 +1,45 @@
+From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001
+From: Petr Matousek <pmatouse@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@redhat.com>
+Reported-by: Matt Tait <matttait@google.com>
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@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
+
diff --git a/emulators/qemu/Makefile b/emulators/qemu/Makefile
index 54bbfd5c5b04..a88ef53ab569 100644
--- a/emulators/qemu/Makefile
+++ b/emulators/qemu/Makefile
@@ -3,7 +3,7 @@
PORTNAME= qemu
PORTVERSION= 0.11.1
-PORTREVISION= 19
+PORTREVISION= 20
CATEGORIES= emulators
MASTER_SITES= SAVANNAH \
http://bellard.org/qemu/
diff --git a/emulators/qemu/files/patch-CVE-2015-3209 b/emulators/qemu/files/patch-CVE-2015-3209
new file mode 100644
index 000000000000..4eb1d6093827
--- /dev/null
+++ b/emulators/qemu/files/patch-CVE-2015-3209
@@ -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)))