svn commit: r394506 - in head/sysutils/xen-tools: . files

Jason Unovitch junovitch at FreeBSD.org
Mon Aug 17 13:55:10 UTC 2015


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 at 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 <bsd.port.options.mk>
 
 .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 <kwolf at redhat.com>
+Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
+---
+ 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 <stefanha at redhat.com>
+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 <stefanha at redhat.com>
+---
+ 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 <stefanha at redhat.com>
+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 <stefanha at redhat.com>
+---
+ 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 (hlen<sizeof(ip_header) || hlen>eth_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 (hlen<sizeof(ip_header) || hlen>eth_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 <stefanha at redhat.com>
+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 <stefanha at redhat.com>
+---
+ 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 <stefanha at redhat.com>
+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 <stefanha at redhat.com>
+---
+ 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 (hlen<sizeof(ip_header) || hlen>eth_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 <stefanha at redhat.com>
+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 <stefanha at redhat.com>
+---
+ 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 <stefanha at redhat.com>
+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 <stefanha at redhat.com>
+---
+ 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 <stefanha at redhat.com>
+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 <stefanha at redhat.com>
+---
+ 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


More information about the svn-ports-all mailing list