[app-emulation/qemu] sync
This commit is contained in:
parent
c8fffc1ee2
commit
27473cf3c1
82
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-1.patch
Normal file
82
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-1.patch
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
From 5e0c290415b9d57077a86e70c8e6a058868334d3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Hajnoczi <stefanha@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@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
|
||||||
|
|
373
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-2.patch
Normal file
373
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-2.patch
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
From 2d7d80e8dc160904fa7276cc05da26c062a50066 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Hajnoczi <stefanha@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@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
|
||||||
|
|
39
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-3.patch
Normal file
39
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-3.patch
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
From 043d28507ef7c5fdc34866f5e3b27a72bd0cd072 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Hajnoczi <stefanha@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@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
|
||||||
|
|
53
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-4.patch
Normal file
53
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-4.patch
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
From 5a75d242fe019d05b46ef9bc330a6892525c84a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Hajnoczi <stefanha@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@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
|
||||||
|
|
34
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-5.patch
Normal file
34
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-5.patch
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
From 6c79ea275d72bc1fd88bdcf1e7d231b2c9c865de Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Hajnoczi <stefanha@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@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
|
||||||
|
|
35
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-6.patch
Normal file
35
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-6.patch
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
From 30aa7be430e7c982e9163f3bcc745d3aa57b6aa4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Hajnoczi <stefanha@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@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
|
||||||
|
|
32
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-7.patch
Normal file
32
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5165-7.patch
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
From 9a084807bf6ca7c16d997a236d304111894a6539 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Stefan Hajnoczi <stefanha@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@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
|
||||||
|
|
36
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5166.patch
Normal file
36
app-emulation/qemu/files/qemu-2.3.0-CVE-2015-5166.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
||||||
|
|
||||||
|
Fix release_drive on unplugged devices (pci_piix3_xen_ide_unplug)
|
||||||
|
|
||||||
|
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@redhat.com>
|
||||||
|
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
||||||
|
|
||||||
|
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
|
||||||
|
index adb6649..5a26c86 100644
|
||||||
|
--- a/hw/ide/piix.c
|
||||||
|
+++ b/hw/ide/piix.c
|
||||||
|
@@ -169,6 +169,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
|
||||||
|
PCIIDEState *pci_ide;
|
||||||
|
DriveInfo *di;
|
||||||
|
int i;
|
||||||
|
+ IDEDevice *idedev;
|
||||||
|
|
||||||
|
pci_ide = PCI_IDE(dev);
|
||||||
|
|
||||||
|
@@ -181,6 +182,12 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
|
||||||
|
blk_detach_dev(blk, ds);
|
||||||
|
}
|
||||||
|
pci_ide->bus[di->bus].ifs[di->unit].blk = NULL;
|
||||||
|
+ if (!(i % 2)) {
|
||||||
|
+ idedev = pci_ide->bus[di->bus].master;
|
||||||
|
+ } else {
|
||||||
|
+ idedev = pci_ide->bus[di->bus].slave;
|
||||||
|
+ }
|
||||||
|
+ idedev->conf.blk = NULL;
|
||||||
|
blk_unref(blk);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
# Copyright 1999-2015 Gentoo Foundation
|
# Copyright 1999-2015 Gentoo Foundation
|
||||||
# Distributed under the terms of the GNU General Public License v2
|
# Distributed under the terms of the GNU General Public License v2
|
||||||
# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu/qemu-2.3.0-r4.ebuild,v 1.1 2015/07/27 19:32:48 cardoe Exp $
|
# $Header: /var/cvsroot/gentoo-x86/app-emulation/qemu/qemu-2.3.0-r5.ebuild,v 1.1 2015/08/03 15:36:55 cardoe Exp $
|
||||||
|
|
||||||
EAPI=5
|
EAPI=5
|
||||||
|
|
||||||
@ -266,7 +266,15 @@ src_prepare() {
|
|||||||
epatch "${FILESDIR}"/${P}-CVE-2015-3214.patch #556052
|
epatch "${FILESDIR}"/${P}-CVE-2015-3214.patch #556052
|
||||||
epatch "${FILESDIR}"/${P}-CVE-2015-5154-1.patch #556050 / #555532
|
epatch "${FILESDIR}"/${P}-CVE-2015-5154-1.patch #556050 / #555532
|
||||||
epatch "${FILESDIR}"/${P}-CVE-2015-5154-2.patch #556050 / #555532
|
epatch "${FILESDIR}"/${P}-CVE-2015-5154-2.patch #556050 / #555532
|
||||||
epatch "${FILESDIR}"/${P}-CVE-2015-5154-3.patch #556050 / #555532`
|
epatch "${FILESDIR}"/${P}-CVE-2015-5154-3.patch #556050 / #555532
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5165-1.patch #556304
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5165-2.patch #556304
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5165-3.patch #556304
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5165-4.patch #556304
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5165-5.patch #556304
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5165-6.patch #556304
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5165-7.patch #556304
|
||||||
|
epatch "${FILESDIR}"/${P}-CVE-2015-5166.patch #556304
|
||||||
[[ -n ${BACKPORTS} ]] && \
|
[[ -n ${BACKPORTS} ]] && \
|
||||||
EPATCH_FORCE=yes EPATCH_SUFFIX="patch" EPATCH_SOURCE="${S}/patches" \
|
EPATCH_FORCE=yes EPATCH_SUFFIX="patch" EPATCH_SOURCE="${S}/patches" \
|
||||||
epatch
|
epatch
|
Loading…
Reference in New Issue
Block a user