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