diff options
author | nox <nox@FreeBSD.org> | 2015-06-27 03:14:41 +0800 |
---|---|---|
committer | nox <nox@FreeBSD.org> | 2015-06-27 03:14:41 +0800 |
commit | 7160e4b0022ce7487fc1d1aa3a6dfdbd5c83e2aa (patch) | |
tree | ad5cdc338b859b6160567370a1aa78c048944383 | |
parent | e8387a7717e75c1f4bd1b9592c841b98fb6cf17a (diff) | |
download | freebsd-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/Makefile | 2 | ||||
-rw-r--r-- | emulators/qemu-devel/files/patch-CVE-2015-3209 | 45 | ||||
-rw-r--r-- | emulators/qemu-sbruno/Makefile | 1 | ||||
-rw-r--r-- | emulators/qemu-sbruno/files/patch-CVE-2015-3209 | 45 | ||||
-rw-r--r-- | emulators/qemu/Makefile | 2 | ||||
-rw-r--r-- | emulators/qemu/files/patch-CVE-2015-3209 | 82 |
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))) |