|
|
b2d9fb |
From ceffa7fb93c4ea570a0c854974a4993eedea52ca Mon Sep 17 00:00:00 2001
|
|
|
b2d9fb |
From: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
b2d9fb |
Date: Fri, 31 Jul 2015 15:59:42 +0200
|
|
|
b2d9fb |
Subject: [PATCH 1/7] rtl8139: avoid nested ifs in IP header parsing
|
|
|
b2d9fb |
(CVE-2015-5165)
|
|
|
b2d9fb |
|
|
|
b2d9fb |
Message-id: <1438358388-10575-2-git-send-email-stefanha@redhat.com>
|
|
|
b2d9fb |
Patchwork-id: 67236
|
|
|
b2d9fb |
O-Subject: [RHEL-7.1.z qemu-kvm EMBARGOED PATCH 1/7] rtl8139: avoid nested ifs in IP header parsing (CVE-2015-5165)
|
|
|
b2d9fb |
Bugzilla: 1248764
|
|
|
b2d9fb |
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
|
|
|
b2d9fb |
RH-Acked-by: Xiao Wang <jasowang@redhat.com>
|
|
|
b2d9fb |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
b2d9fb |
|
|
|
b2d9fb |
Transmit offload needs to parse packet headers. If header fields have
|
|
|
b2d9fb |
unexpected values the offload processing is skipped.
|
|
|
b2d9fb |
|
|
|
b2d9fb |
The code currently uses nested ifs because there is relatively little
|
|
|
b2d9fb |
input validation. The next patches will add missing input validation
|
|
|
b2d9fb |
and a goto label is more appropriate to avoid deep if statement nesting.
|
|
|
b2d9fb |
|
|
|
b2d9fb |
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
b2d9fb |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
b2d9fb |
---
|
|
|
b2d9fb |
hw/net/rtl8139.c | 41 ++++++++++++++++++++++-------------------
|
|
|
b2d9fb |
1 file changed, 22 insertions(+), 19 deletions(-)
|
|
|
b2d9fb |
|
|
|
b2d9fb |
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
|
|
|
b2d9fb |
index d08106b..e3b594f 100644
|
|
|
b2d9fb |
--- a/hw/net/rtl8139.c
|
|
|
b2d9fb |
+++ b/hw/net/rtl8139.c
|
|
|
b2d9fb |
@@ -2152,28 +2152,30 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
|
|
|
b2d9fb |
size_t eth_payload_len = 0;
|
|
|
b2d9fb |
|
|
|
b2d9fb |
int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));
|
|
|
b2d9fb |
- if (proto == ETH_P_IP)
|
|
|
b2d9fb |
+ if (proto != ETH_P_IP)
|
|
|
b2d9fb |
{
|
|
|
b2d9fb |
- DPRINTF("+++ C+ mode has IP packet\n");
|
|
|
b2d9fb |
-
|
|
|
b2d9fb |
- /* not aligned */
|
|
|
b2d9fb |
- eth_payload_data = saved_buffer + ETH_HLEN;
|
|
|
b2d9fb |
- eth_payload_len = saved_size - ETH_HLEN;
|
|
|
b2d9fb |
-
|
|
|
b2d9fb |
- ip = (ip_header*)eth_payload_data;
|
|
|
b2d9fb |
-
|
|
|
b2d9fb |
- if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
|
|
|
b2d9fb |
- DPRINTF("+++ C+ mode packet has bad IP version %d "
|
|
|
b2d9fb |
- "expected %d\n", IP_HEADER_VERSION(ip),
|
|
|
b2d9fb |
- IP_HEADER_VERSION_4);
|
|
|
b2d9fb |
- ip = NULL;
|
|
|
b2d9fb |
- } else {
|
|
|
b2d9fb |
- hlen = IP_HEADER_LENGTH(ip);
|
|
|
b2d9fb |
- ip_protocol = ip->ip_p;
|
|
|
b2d9fb |
- ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
|
|
|
b2d9fb |
- }
|
|
|
b2d9fb |
+ goto skip_offload;
|
|
|
b2d9fb |
}
|
|
|
b2d9fb |
|
|
|
b2d9fb |
+ DPRINTF("+++ C+ mode has IP packet\n");
|
|
|
b2d9fb |
+
|
|
|
b2d9fb |
+ /* not aligned */
|
|
|
b2d9fb |
+ eth_payload_data = saved_buffer + ETH_HLEN;
|
|
|
b2d9fb |
+ eth_payload_len = saved_size - ETH_HLEN;
|
|
|
b2d9fb |
+
|
|
|
b2d9fb |
+ ip = (ip_header*)eth_payload_data;
|
|
|
b2d9fb |
+
|
|
|
b2d9fb |
+ if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {
|
|
|
b2d9fb |
+ DPRINTF("+++ C+ mode packet has bad IP version %d "
|
|
|
b2d9fb |
+ "expected %d\n", IP_HEADER_VERSION(ip),
|
|
|
b2d9fb |
+ IP_HEADER_VERSION_4);
|
|
|
b2d9fb |
+ goto skip_offload;
|
|
|
b2d9fb |
+ }
|
|
|
b2d9fb |
+
|
|
|
b2d9fb |
+ hlen = IP_HEADER_LENGTH(ip);
|
|
|
b2d9fb |
+ ip_protocol = ip->ip_p;
|
|
|
b2d9fb |
+ ip_data_len = be16_to_cpu(ip->ip_len) - hlen;
|
|
|
b2d9fb |
+
|
|
|
b2d9fb |
if (ip)
|
|
|
b2d9fb |
{
|
|
|
b2d9fb |
if (txdw0 & CP_TX_IPCS)
|
|
|
b2d9fb |
@@ -2369,6 +2371,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
|
|
|
b2d9fb |
}
|
|
|
b2d9fb |
}
|
|
|
b2d9fb |
|
|
|
b2d9fb |
+skip_offload:
|
|
|
b2d9fb |
/* update tally counter */
|
|
|
b2d9fb |
++s->tally_counters.TxOk;
|
|
|
b2d9fb |
|
|
|
b2d9fb |
--
|
|
|
b2d9fb |
1.8.3.1
|
|
|
b2d9fb |
|