Date: Fri, 26 Jun 2015 19:14:41 +0000 (UTC) From: Juergen Lock <nox@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r390664 - in head/emulators: qemu qemu-devel qemu-devel/files qemu-sbruno qemu-sbruno/files qemu/files Message-ID: <201506261914.t5QJEfN2014820@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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@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 + 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@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 + 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)))
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506261914.t5QJEfN2014820>