From owner-svn-ports-all@freebsd.org Mon Aug 17 13:55:10 2015 Return-Path: Delivered-To: svn-ports-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A84F69BBA24; Mon, 17 Aug 2015 13:55:10 +0000 (UTC) (envelope-from junovitch@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 96AA71997; Mon, 17 Aug 2015 13:55:10 +0000 (UTC) (envelope-from junovitch@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t7HDtA7g027086; Mon, 17 Aug 2015 13:55:10 GMT (envelope-from junovitch@FreeBSD.org) Received: (from junovitch@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7HDt728027066; Mon, 17 Aug 2015 13:55:07 GMT (envelope-from junovitch@FreeBSD.org) Message-Id: <201508171355.t7HDt728027066@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: junovitch set sender to junovitch@FreeBSD.org using -f From: Jason Unovitch Date: Mon, 17 Aug 2015 13:55:07 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r394506 - in head/sysutils/xen-tools: . files X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Aug 2015 13:55:10 -0000 Author: junovitch Date: Mon Aug 17 13:55:06 2015 New Revision: 394506 URL: https://svnweb.freebsd.org/changeset/ports/394506 Log: sysutils/xen-tools: Update to 4.5.1 and apply XSA-139/XSA-140 patches - Update to 4.5.1 - Remove XSA-117 to XSA-136 and elf_parse_bsdsyms patches now part of 4.5.1 - Leave XSA-135 QEMU traditional patches due an oversight in 4.5.1 - Apply patches for XSA-139/XSA-140 - Set USE_LDCONFIG, sort USES, use ${PATCH}, and reorder Makefile (portlint) PR: 201931 Security: CVE-2015-5166 Security: ee99899d-4347-11e5-93ad-002590263bf5 Security: CVE-2015-5165 Security: f06f20dc-4347-11e5-93ad-002590263bf5 Approved by: bapt (maintainer), feld (mentor) MFH: 2015Q3 Added: head/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch (contents, props changed) head/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch (contents, props changed) head/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch (contents, props changed) head/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch (contents, props changed) head/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch (contents, props changed) head/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch (contents, props changed) head/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch (contents, props changed) head/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch (contents, props changed) Deleted: head/sysutils/xen-tools/files/0001-libelf-fix-elf_parse_bsdsyms-call.patch head/sysutils/xen-tools/files/xsa119-unstable.patch head/sysutils/xen-tools/files/xsa125.patch head/sysutils/xen-tools/files/xsa126-qemut.patch head/sysutils/xen-tools/files/xsa126-qemuu.patch head/sysutils/xen-tools/files/xsa128-qemut.patch head/sysutils/xen-tools/files/xsa128-qemuu.patch head/sysutils/xen-tools/files/xsa129-qemut.patch head/sysutils/xen-tools/files/xsa129-qemuu.patch head/sysutils/xen-tools/files/xsa130-qemut.patch head/sysutils/xen-tools/files/xsa130-qemuu.patch head/sysutils/xen-tools/files/xsa131-qemut-1.patch head/sysutils/xen-tools/files/xsa131-qemut-2.patch head/sysutils/xen-tools/files/xsa131-qemut-3.patch head/sysutils/xen-tools/files/xsa131-qemut-4.patch head/sysutils/xen-tools/files/xsa131-qemut-5.patch head/sysutils/xen-tools/files/xsa131-qemut-6.patch head/sysutils/xen-tools/files/xsa131-qemut-7.patch head/sysutils/xen-tools/files/xsa131-qemut-8.patch head/sysutils/xen-tools/files/xsa131-qemuu-1.patch head/sysutils/xen-tools/files/xsa131-qemuu-2.patch head/sysutils/xen-tools/files/xsa131-qemuu-3.patch head/sysutils/xen-tools/files/xsa131-qemuu-4.patch head/sysutils/xen-tools/files/xsa131-qemuu-5.patch head/sysutils/xen-tools/files/xsa131-qemuu-6.patch head/sysutils/xen-tools/files/xsa131-qemuu-7.patch head/sysutils/xen-tools/files/xsa131-qemuu-8.patch head/sysutils/xen-tools/files/xsa133-qemut.patch head/sysutils/xen-tools/files/xsa133-qemuu.patch head/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch head/sysutils/xen-tools/files/xsa135-qemuu-4.5-2.patch Modified: head/sysutils/xen-tools/Makefile head/sysutils/xen-tools/distinfo head/sysutils/xen-tools/pkg-plist Modified: head/sysutils/xen-tools/Makefile ============================================================================== --- head/sysutils/xen-tools/Makefile Mon Aug 17 13:51:23 2015 (r394505) +++ head/sysutils/xen-tools/Makefile Mon Aug 17 13:55:06 2015 (r394506) @@ -1,12 +1,11 @@ # $FreeBSD$ PORTNAME= xen -PKGNAMESUFFIX= -tools -PORTVERSION= 4.5.0 -PORTREVISION= 9 +PORTVERSION= 4.5.1 CATEGORIES= sysutils emulators MASTER_SITES= http://bits.xensource.com/oss-xen/release/${PORTVERSION}/ \ http://code.coreboot.org/p/seabios/downloads/get/:seabios +PKGNAMESUFFIX= -tools MAINTAINER= bapt@FreeBSD.org COMMENT= Xen management tool, based on LibXenlight @@ -14,13 +13,13 @@ COMMENT= Xen management tool, based on L LICENSE= GPLv2 LGPL3 LICENSE_COMB= multi -OPTIONS_DEFINE= DOCS - LIB_DEPENDS= libyajl.so:${PORTSDIR}/devel/yajl \ liblzo2.so:${PORTSDIR}/archivers/lzo2 \ libpixman-1.so:${PORTSDIR}/x11/pixman BUILD_DEPENDS= dev86>0:${PORTSDIR}/devel/dev86 +OPTIONS_DEFINE= DOCS + ONLY_FOR_ARCHS= amd64 ONLY_FOR_ARCHS_REASON= "not yet ported to anything other than amd64" @@ -30,8 +29,9 @@ DISTFILES+= ${DISTNAME}.tar.gz \ WRKSRC= ${WRKDIR}/xen-${PORTVERSION} -USES= cpe gmake perl5 python shebangfix libtool pkgconfig +USES= cpe gmake libtool perl5 pkgconfig python shebangfix USE_GNOME= glib20 +USE_LDCONFIG= yes GNU_CONFIGURE= yes CONFIGURE_ENV= HOSTCC="${CC}" CC="${CC}" \ ac_cv_path_BASH=${TRUE} \ @@ -47,10 +47,7 @@ QEMU_ARGS= --disable-gtk \ --disable-curl \ --cxx=c++ -EXTRA_PATCHES= ${FILESDIR}/xsa119-unstable.patch:-p1 \ - ${FILESDIR}/xsa125.patch:-p1 \ - ${FILESDIR}/xsa137.patch:-p1 \ - ${FILESDIR}/0001-libelf-fix-elf_parse_bsdsyms-call.patch:-p1 \ +EXTRA_PATCHES= ${FILESDIR}/xsa137.patch:-p1 \ ${FILESDIR}/0002-libxc-fix-xc_dom_load_elf_symtab.patch:-p1 CONFIGURE_ARGS+= --with-extra-qemuu-configure-args="${QEMU_ARGS}" @@ -63,7 +60,7 @@ INSTALL_TARGET= install-tools install-do .include .if ${OPSYS} != FreeBSD -IGNORE= Only supported on FreeBSD +IGNORE= only supported on FreeBSD .endif post-extract: @@ -80,11 +77,11 @@ post-patch: ${WRKSRC}/docs/man/* @for p in ${FILESDIR}/*qemut*.patch; do \ ${ECHO_CMD} "====> Applying $${p##*/}" ; \ - patch -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen-traditional ; \ + ${PATCH} -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen-traditional ; \ done @for p in ${FILESDIR}/*qemuu*.patch; do \ ${ECHO_CMD} "====> Applying $${p##*/}" ; \ - patch -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen ; \ + ${PATCH} -s -p1 -i $${p} -d ${WRKSRC}/tools/qemu-xen ; \ done post-install: Modified: head/sysutils/xen-tools/distinfo ============================================================================== --- head/sysutils/xen-tools/distinfo Mon Aug 17 13:51:23 2015 (r394505) +++ head/sysutils/xen-tools/distinfo Mon Aug 17 13:55:06 2015 (r394506) @@ -1,4 +1,4 @@ -SHA256 (xen-4.5.0.tar.gz) = 5bdb40e2b28d2eeb541bd71a9777f40cbe2ae444b987521d33f099541a006f3b -SIZE (xen-4.5.0.tar.gz) = 18404933 +SHA256 (xen-4.5.1.tar.gz) = 668c11d4fca67ac44329e369f810356eacd37b28d28fb96e66aac77f3c5e1371 +SIZE (xen-4.5.1.tar.gz) = 18410400 SHA256 (seabios-1.8.1.tar.gz) = 283bd848f5ce9d4bc52add973a856347e02c9ce89a9e6bc92c99359b87c9871d SIZE (seabios-1.8.1.tar.gz) = 537712 Added: head/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa139-qemuu-4.5.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,38 @@ +pci_piix3_xen_ide_unplug should completely unhook the unplugged +IDEDevice from the corresponding BlockBackend, otherwise the next call +to release_drive will try to detach the drive again. + +Suggested-by: Kevin Wolf +Signed-off-by: Stefano Stabellini +--- + hw/ide/piix.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/hw/ide/piix.c b/hw/ide/piix.c +index 40757eb..0524dce 100644 +--- a/hw/ide/piix.c ++++ b/hw/ide/piix.c +@@ -172,6 +172,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) + PCIIDEState *pci_ide; + DriveInfo *di; + int i = 0; ++ IDEDevice *idedev; + + pci_ide = PCI_IDE(dev); + +@@ -184,6 +185,12 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev) + } + bdrv_close(di->bdrv); + pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; ++ if (!(i % 2)) { ++ idedev = pci_ide->bus[di->bus].master; ++ } else { ++ idedev = pci_ide->bus[di->bus].slave; ++ } ++ idedev->conf.bs = NULL; + drive_put_ref(di); + } + } +-- +2.1.4 + Added: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-1.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,82 @@ +From 5e0c290415b9d57077a86e70c8e6a058868334d3 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 15 Jul 2015 18:16:58 +0100 +Subject: [PATCH 1/7] rtl8139: avoid nested ifs in IP header parsing + +Transmit offload needs to parse packet headers. If header fields have +unexpected values the offload processing is skipped. + +The code currently uses nested ifs because there is relatively little +input validation. The next patches will add missing input validation +and a goto label is more appropriate to avoid deep if statement nesting. + +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 41 ++++++++++++++++++++++------------------- + 1 file changed, 22 insertions(+), 19 deletions(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 5f0197c..91ba33b 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2174,28 +2174,30 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + size_t eth_payload_len = 0; + + int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); +- if (proto == ETH_P_IP) ++ if (proto != ETH_P_IP) + { +- DPRINTF("+++ C+ mode has IP packet\n"); +- +- /* not aligned */ +- eth_payload_data = saved_buffer + ETH_HLEN; +- eth_payload_len = saved_size - ETH_HLEN; +- +- ip = (ip_header*)eth_payload_data; +- +- if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { +- DPRINTF("+++ C+ mode packet has bad IP version %d " +- "expected %d\n", IP_HEADER_VERSION(ip), +- IP_HEADER_VERSION_4); +- ip = NULL; +- } else { +- hlen = IP_HEADER_LENGTH(ip); +- ip_protocol = ip->ip_p; +- ip_data_len = be16_to_cpu(ip->ip_len) - hlen; +- } ++ goto skip_offload; + } + ++ DPRINTF("+++ C+ mode has IP packet\n"); ++ ++ /* not aligned */ ++ eth_payload_data = saved_buffer + ETH_HLEN; ++ eth_payload_len = saved_size - ETH_HLEN; ++ ++ ip = (ip_header*)eth_payload_data; ++ ++ if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { ++ DPRINTF("+++ C+ mode packet has bad IP version %d " ++ "expected %d\n", IP_HEADER_VERSION(ip), ++ IP_HEADER_VERSION_4); ++ goto skip_offload; ++ } ++ ++ hlen = IP_HEADER_LENGTH(ip); ++ ip_protocol = ip->ip_p; ++ ip_data_len = be16_to_cpu(ip->ip_len) - hlen; ++ + if (ip) + { + if (txdw0 & CP_TX_IPCS) +@@ -2391,6 +2393,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + } + } + ++skip_offload: + /* update tally counter */ + ++s->tally_counters.TxOk; + +-- +2.1.4 + Added: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-2.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,373 @@ +From 2d7d80e8dc160904fa7276cc05da26c062a50066 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 15 Jul 2015 18:16:59 +0100 +Subject: [PATCH 2/7] rtl8139: drop tautologous if (ip) {...} statement + +The previous patch stopped using the ip pointer as an indicator that the +IP header is present. When we reach the if (ip) {...} statement we know +ip is always non-NULL. + +Remove the if statement to reduce nesting. + +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 305 +++++++++++++++++++++++++++---------------------------- + 1 file changed, 151 insertions(+), 154 deletions(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 91ba33b..2f12d42 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2198,198 +2198,195 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + ip_protocol = ip->ip_p; + ip_data_len = be16_to_cpu(ip->ip_len) - hlen; + +- if (ip) ++ if (txdw0 & CP_TX_IPCS) + { +- if (txdw0 & CP_TX_IPCS) +- { +- DPRINTF("+++ C+ mode need IP checksum\n"); ++ DPRINTF("+++ C+ mode need IP checksum\n"); + +- if (hleneth_payload_len) {/* min header length */ +- /* bad packet header len */ +- /* or packet too short */ +- } +- else +- { +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(ip, hlen); +- DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", +- hlen, ip->ip_sum); +- } ++ if (hleneth_payload_len) {/* min header length */ ++ /* bad packet header len */ ++ /* or packet too short */ + } +- +- if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) ++ else + { +- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(ip, hlen); ++ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", ++ hlen, ip->ip_sum); ++ } ++ } + +- DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " +- "frame data %d specified MSS=%d\n", ETH_MTU, +- ip_data_len, saved_size - ETH_HLEN, large_send_mss); ++ if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) ++ { ++ int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; + +- int tcp_send_offset = 0; +- int send_count = 0; ++ DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " ++ "frame data %d specified MSS=%d\n", ETH_MTU, ++ ip_data_len, saved_size - ETH_HLEN, large_send_mss); + +- /* maximum IP header length is 60 bytes */ +- uint8_t saved_ip_header[60]; ++ int tcp_send_offset = 0; ++ int send_count = 0; + +- /* save IP header template; data area is used in tcp checksum calculation */ +- memcpy(saved_ip_header, eth_payload_data, hlen); ++ /* maximum IP header length is 60 bytes */ ++ uint8_t saved_ip_header[60]; + +- /* a placeholder for checksum calculation routine in tcp case */ +- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ /* save IP header template; data area is used in tcp checksum calculation */ ++ memcpy(saved_ip_header, eth_payload_data, hlen); + +- /* pointer to TCP header */ +- tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); ++ /* a placeholder for checksum calculation routine in tcp case */ ++ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; ++ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; + +- int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); ++ /* pointer to TCP header */ ++ tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); + +- /* ETH_MTU = ip header len + tcp header len + payload */ +- int tcp_data_len = ip_data_len - tcp_hlen; +- int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; ++ int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + +- DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " +- "data len %d TCP chunk size %d\n", ip_data_len, +- tcp_hlen, tcp_data_len, tcp_chunk_size); ++ /* ETH_MTU = ip header len + tcp header len + payload */ ++ int tcp_data_len = ip_data_len - tcp_hlen; ++ int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; + +- /* note the cycle below overwrites IP header data, +- but restores it from saved_ip_header before sending packet */ ++ DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " ++ "data len %d TCP chunk size %d\n", ip_data_len, ++ tcp_hlen, tcp_data_len, tcp_chunk_size); + +- int is_last_frame = 0; ++ /* note the cycle below overwrites IP header data, ++ but restores it from saved_ip_header before sending packet */ + +- for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) +- { +- uint16_t chunk_size = tcp_chunk_size; +- +- /* check if this is the last frame */ +- if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) +- { +- is_last_frame = 1; +- chunk_size = tcp_data_len - tcp_send_offset; +- } +- +- DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", +- be32_to_cpu(p_tcp_hdr->th_seq)); +- +- /* add 4 TCP pseudoheader fields */ +- /* copy IP source and destination fields */ +- memcpy(data_to_checksum, saved_ip_header + 12, 8); +- +- DPRINTF("+++ C+ mode TSO calculating TCP checksum for " +- "packet with %d bytes data\n", tcp_hlen + +- chunk_size); +- +- if (tcp_send_offset) +- { +- memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); +- } +- +- /* keep PUSH and FIN flags only for the last frame */ +- if (!is_last_frame) +- { +- TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); +- } +- +- /* recalculate TCP checksum */ +- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_tcpip_hdr->zeros = 0; +- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; +- p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); +- +- p_tcp_hdr->th_sum = 0; +- +- int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); +- DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", +- tcp_checksum); +- +- p_tcp_hdr->th_sum = tcp_checksum; +- +- /* restore IP header */ +- memcpy(eth_payload_data, saved_ip_header, hlen); +- +- /* set IP data length and recalculate IP checksum */ +- ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); +- +- /* increment IP id for subsequent frames */ +- ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); +- +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(eth_payload_data, hlen); +- DPRINTF("+++ C+ mode TSO IP header len=%d " +- "checksum=%04x\n", hlen, ip->ip_sum); +- +- int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; +- DPRINTF("+++ C+ mode TSO transferring packet size " +- "%d\n", tso_send_size); +- rtl8139_transfer_frame(s, saved_buffer, tso_send_size, +- 0, (uint8_t *) dot1q_buffer); +- +- /* add transferred count to TCP sequence number */ +- p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); +- ++send_count; +- } ++ int is_last_frame = 0; + +- /* Stop sending this frame */ +- saved_size = 0; +- } +- else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) ++ for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) + { +- DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); ++ uint16_t chunk_size = tcp_chunk_size; + +- /* maximum IP header length is 60 bytes */ +- uint8_t saved_ip_header[60]; +- memcpy(saved_ip_header, eth_payload_data, hlen); ++ /* check if this is the last frame */ ++ if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) ++ { ++ is_last_frame = 1; ++ chunk_size = tcp_data_len - tcp_send_offset; ++ } + +- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", ++ be32_to_cpu(p_tcp_hdr->th_seq)); + + /* add 4 TCP pseudoheader fields */ + /* copy IP source and destination fields */ + memcpy(data_to_checksum, saved_ip_header + 12, 8); + +- if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) ++ DPRINTF("+++ C+ mode TSO calculating TCP checksum for " ++ "packet with %d bytes data\n", tcp_hlen + ++ chunk_size); ++ ++ if (tcp_send_offset) + { +- DPRINTF("+++ C+ mode calculating TCP checksum for " +- "packet with %d bytes data\n", ip_data_len); ++ memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); ++ } + +- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_tcpip_hdr->zeros = 0; +- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; +- p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ /* keep PUSH and FIN flags only for the last frame */ ++ if (!is_last_frame) ++ { ++ TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); ++ } + +- tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); ++ /* recalculate TCP checksum */ ++ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_tcpip_hdr->zeros = 0; ++ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; ++ p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); + +- p_tcp_hdr->th_sum = 0; ++ p_tcp_hdr->th_sum = 0; + +- int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); +- DPRINTF("+++ C+ mode TCP checksum %04x\n", +- tcp_checksum); ++ int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); ++ DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", ++ tcp_checksum); + +- p_tcp_hdr->th_sum = tcp_checksum; +- } +- else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) +- { +- DPRINTF("+++ C+ mode calculating UDP checksum for " +- "packet with %d bytes data\n", ip_data_len); ++ p_tcp_hdr->th_sum = tcp_checksum; + +- ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_udpip_hdr->zeros = 0; +- p_udpip_hdr->ip_proto = IP_PROTO_UDP; +- p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ /* restore IP header */ ++ memcpy(eth_payload_data, saved_ip_header, hlen); + +- udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); ++ /* set IP data length and recalculate IP checksum */ ++ ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); + +- p_udp_hdr->uh_sum = 0; ++ /* increment IP id for subsequent frames */ ++ ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); + +- int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); +- DPRINTF("+++ C+ mode UDP checksum %04x\n", +- udp_checksum); ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(eth_payload_data, hlen); ++ DPRINTF("+++ C+ mode TSO IP header len=%d " ++ "checksum=%04x\n", hlen, ip->ip_sum); + +- p_udp_hdr->uh_sum = udp_checksum; +- } ++ int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; ++ DPRINTF("+++ C+ mode TSO transferring packet size " ++ "%d\n", tso_send_size); ++ rtl8139_transfer_frame(s, saved_buffer, tso_send_size, ++ 0, (uint8_t *) dot1q_buffer); + +- /* restore IP header */ +- memcpy(eth_payload_data, saved_ip_header, hlen); ++ /* add transferred count to TCP sequence number */ ++ p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); ++ ++send_count; + } ++ ++ /* Stop sending this frame */ ++ saved_size = 0; ++ } ++ else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) ++ { ++ DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); ++ ++ /* maximum IP header length is 60 bytes */ ++ uint8_t saved_ip_header[60]; ++ memcpy(saved_ip_header, eth_payload_data, hlen); ++ ++ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; ++ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ ++ /* add 4 TCP pseudoheader fields */ ++ /* copy IP source and destination fields */ ++ memcpy(data_to_checksum, saved_ip_header + 12, 8); ++ ++ if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) ++ { ++ DPRINTF("+++ C+ mode calculating TCP checksum for " ++ "packet with %d bytes data\n", ip_data_len); ++ ++ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_tcpip_hdr->zeros = 0; ++ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; ++ p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ ++ tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); ++ ++ p_tcp_hdr->th_sum = 0; ++ ++ int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); ++ DPRINTF("+++ C+ mode TCP checksum %04x\n", ++ tcp_checksum); ++ ++ p_tcp_hdr->th_sum = tcp_checksum; ++ } ++ else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) ++ { ++ DPRINTF("+++ C+ mode calculating UDP checksum for " ++ "packet with %d bytes data\n", ip_data_len); ++ ++ ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_udpip_hdr->zeros = 0; ++ p_udpip_hdr->ip_proto = IP_PROTO_UDP; ++ p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ ++ udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); ++ ++ p_udp_hdr->uh_sum = 0; ++ ++ int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); ++ DPRINTF("+++ C+ mode UDP checksum %04x\n", ++ udp_checksum); ++ ++ p_udp_hdr->uh_sum = udp_checksum; ++ } ++ ++ /* restore IP header */ ++ memcpy(eth_payload_data, saved_ip_header, hlen); + } + } + +-- +2.1.4 + Added: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-3.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,39 @@ +From 043d28507ef7c5fdc34866f5e3b27a72bd0cd072 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 15 Jul 2015 18:17:00 +0100 +Subject: [PATCH 3/7] rtl8139: skip offload on short Ethernet/IP header + +Transmit offload features access Ethernet and IP headers the packet. If +the packet is too short we must not attempt to access header fields: + + int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); + ... + eth_payload_data = saved_buffer + ETH_HLEN; + ... + ip = (ip_header*)eth_payload_data; + if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { + +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 2f12d42..d377b6b 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2164,6 +2164,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + { + DPRINTF("+++ C+ mode offloaded task checksum\n"); + ++ /* Large enough for Ethernet and IP headers? */ ++ if (saved_size < ETH_HLEN + sizeof(ip_header)) { ++ goto skip_offload; ++ } ++ + /* ip packet header */ + ip_header *ip = NULL; + int hlen = 0; +-- +2.1.4 + Added: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-4.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,53 @@ +From 5a75d242fe019d05b46ef9bc330a6892525c84a7 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 15 Jul 2015 18:17:01 +0100 +Subject: [PATCH 4/7] rtl8139: check IP Header Length field + +The IP Header Length field was only checked in the IP checksum case, but +is used in other cases too. + +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index d377b6b..cd5ac05 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2200,6 +2200,10 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + } + + hlen = IP_HEADER_LENGTH(ip); ++ if (hlen < sizeof(ip_header) || hlen > eth_payload_len) { ++ goto skip_offload; ++ } ++ + ip_protocol = ip->ip_p; + ip_data_len = be16_to_cpu(ip->ip_len) - hlen; + +@@ -2207,17 +2211,10 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + { + DPRINTF("+++ C+ mode need IP checksum\n"); + +- if (hleneth_payload_len) {/* min header length */ +- /* bad packet header len */ +- /* or packet too short */ +- } +- else +- { +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(ip, hlen); +- DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", +- hlen, ip->ip_sum); +- } ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(ip, hlen); ++ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", ++ hlen, ip->ip_sum); + } + + if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) +-- +2.1.4 + Added: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-5.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,34 @@ +From 6c79ea275d72bc1fd88bdcf1e7d231b2c9c865de Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 15 Jul 2015 18:17:02 +0100 +Subject: [PATCH 5/7] rtl8139: check IP Total Length field + +The IP Total Length field includes the IP header and data. Make sure it +is valid and does not exceed the Ethernet payload size. + +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index cd5ac05..ed2b23b 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2205,7 +2205,12 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + } + + ip_protocol = ip->ip_p; +- ip_data_len = be16_to_cpu(ip->ip_len) - hlen; ++ ++ ip_data_len = be16_to_cpu(ip->ip_len); ++ if (ip_data_len < hlen || ip_data_len > eth_payload_len) { ++ goto skip_offload; ++ } ++ ip_data_len -= hlen; + + if (txdw0 & CP_TX_IPCS) + { +-- +2.1.4 + Added: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-6.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,35 @@ +From 30aa7be430e7c982e9163f3bcc745d3aa57b6aa4 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 15 Jul 2015 18:17:03 +0100 +Subject: [PATCH 6/7] rtl8139: skip offload on short TCP header + +TCP Large Segment Offload accesses the TCP header in the packet. If the +packet is too short we must not attempt to access header fields: + + tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); + int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index ed2b23b..c8f0df9 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2224,6 +2224,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + + if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) + { ++ /* Large enough for the TCP header? */ ++ if (ip_data_len < sizeof(tcp_header)) { ++ goto skip_offload; ++ } ++ + int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; + + DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " +-- +2.1.4 + Added: head/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sysutils/xen-tools/files/xsa140-qemuu-unstable-7.patch Mon Aug 17 13:55:06 2015 (r394506) @@ -0,0 +1,32 @@ +From 9a084807bf6ca7c16d997a236d304111894a6539 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 15 Jul 2015 18:17:04 +0100 +Subject: [PATCH 7/7] rtl8139: check TCP Data Offset field + +The TCP Data Offset field contains the length of the header. Make sure +it is valid and does not exceed the IP data length. + +Signed-off-by: Stefan Hajnoczi +--- + hw/net/rtl8139.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index c8f0df9..2df4a51 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -2253,6 +2253,11 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s) + + int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + ++ /* Invalid TCP data offset? */ ++ if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) { ++ goto skip_offload; ++ } ++ + /* ETH_MTU = ip header len + tcp header len + payload */ + int tcp_data_len = ip_data_len - tcp_hlen; + int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; +-- +2.1.4 + Modified: head/sysutils/xen-tools/pkg-plist ============================================================================== --- head/sysutils/xen-tools/pkg-plist Mon Aug 17 13:51:23 2015 (r394505) +++ head/sysutils/xen-tools/pkg-plist Mon Aug 17 13:55:06 2015 (r394506) @@ -36,6 +36,7 @@ include/libxl_event.h include/libxl_json.h include/libxl_utils.h include/libxl_uuid.h +include/libxlutil.h include/xen/COPYING include/xen/arch-arm.h include/xen/arch-arm/hvm/save.h