cce96bf59a
Fix qemu-img map crash for unaligned image (bz #1229394) CVE-2015-3209: pcnet: multi-tmd buffer overflow in the tx path (bz #1230536) CVE-2015-3214: i8254: out-of-bounds memory access (bz #1243728) CVE-2015-5158: scsi stack buffer overflow (bz #1246025) CVE-2015-5154: ide: atapi: heap overflow during I/O buffer memory access (bz #1247141) CVE-2015-5166: BlockBackend object use after free issue (bz #1249758) CVE-2015-5745: buffer overflow in virtio-serial (bz #1251160) CVE-2015-5165: rtl8139 uninitialized heap memory information leakage to guest (bz #1249755)
86 lines
3.0 KiB
Diff
86 lines
3.0 KiB
Diff
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
Date: Wed, 15 Jul 2015 17:13:32 +0100
|
|
Subject: [PATCH] rtl8139: avoid nested ifs in IP header parsing
|
|
(CVE-2015-5165)
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
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.
|
|
|
|
Reported-by: 朱东海(启路) <donghai.zdh@alibaba-inc.com>
|
|
Reviewed-by: Jason Wang <jasowang@redhat.com>
|
|
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
(cherry picked from commit 39b8e7dcaf04cbdb926b478f825b160d852752b5)
|
|
---
|
|
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 f868108..8306b26 100644
|
|
--- a/hw/net/rtl8139.c
|
|
+++ b/hw/net/rtl8139.c
|
|
@@ -2160,28 +2160,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)
|
|
@@ -2377,6 +2379,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
|
|
}
|
|
}
|
|
|
|
+skip_offload:
|
|
/* update tally counter */
|
|
++s->tally_counters.TxOk;
|
|
|