From 6eb82d08e0f1eeeade729e052b8e1d6e56d2d1f8 Mon Sep 17 00:00:00 2001 From: basil00 Date: Wed, 31 Jul 2019 08:46:01 +0800 Subject: [PATCH] Fix WinDivert 2.0 driver bugs. - BSOD for incomplete transport headers (#202). - Fix enforcement of wrong MTU. - Fix missing endpoint handles for IPV6 flow layer. --- CHANGELOG | 5 +++++ VERSION | 2 +- sys/windivert.c | 16 ++++++++++------ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7ee21d1..8a03b23 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -297,3 +297,8 @@ WinDivert 2.0.1-rc - Rename the following functions for consistency: * WinDivertHelperNtohIpv6Address -> WinDivertHelperNtohIPv6Address * WinDivertHelperHtonIpv6Address -> WinDivertHelperHtonIPv6Address +WinDivert 2.0.2-rc + - Fix BSOD caused by packets with missing or incomplete transport + headers. This bug does not affect WinDivert 1.4.*. + - Fix driver max MTU enforcement. + - Fix missing Flow.EndpointId and Flow.ParentEndpointId for IPv6 flows. diff --git a/VERSION b/VERSION index 45e0a92..904a390 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.0.1-rc +2.0.2-rc diff --git a/sys/windivert.c b/sys/windivert.c index 5937c23..ed0578d 100644 --- a/sys/windivert.c +++ b/sys/windivert.c @@ -3892,6 +3892,8 @@ static void windivert_flow_established_v6_classify( UNREFERENCED_PARAMETER(data); UNREFERENCED_PARAMETER(flow_context); + flow_data.ProcessId = (UINT32)meta_vals->processId; + flow_data.ParentEndpointId = meta_vals->parentEndpointHandle; flow_data.ProcessId = (UINT32)meta_vals->processId; windivert_get_ipv6_addr(fixed_vals, FWPS_FIELD_ALE_FLOW_ESTABLISHED_V6_IP_LOCAL_ADDRESS, @@ -4812,7 +4814,7 @@ static BOOL windivert_queue_work(context_t context, PVOID packet, case WINDIVERT_LAYER_NETWORK_FORWARD: buffer = (PNET_BUFFER)packet; network_data = (PWINDIVERT_DATA_NETWORK)layer_data; - if (packet_len > UINT16_MAX) + if (packet_len > WINDIVERT_MTU_MAX) { // Cannot handle oversized packet return TRUE; @@ -5387,30 +5389,32 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4, } } + header_len = ip_header_len; switch (proto) { case IPPROTO_ICMP: icmp_header = (PWINDIVERT_ICMPHDR)NdisGetDataBuffer(buffer, sizeof(WINDIVERT_ICMPHDR), NULL, 1, 0); - header_len = ip_header_len + sizeof(WINDIVERT_ICMPHDR); + header_len += (icmp_header == NULL? 0: sizeof(WINDIVERT_ICMPHDR)); break; case IPPROTO_ICMPV6: icmpv6_header = (PWINDIVERT_ICMPV6HDR)NdisGetDataBuffer(buffer, sizeof(WINDIVERT_ICMPV6HDR), NULL, 1, 0); - header_len = ip_header_len + sizeof(WINDIVERT_ICMPV6HDR); + header_len += + (icmpv6_header == NULL? 0: sizeof(WINDIVERT_ICMPV6HDR)); break; case IPPROTO_TCP: tcp_header = (PWINDIVERT_TCPHDR)NdisGetDataBuffer(buffer, sizeof(WINDIVERT_TCPHDR), NULL, 1, 0); - header_len = ip_header_len + tcp_header->HdrLength*sizeof(UINT32); + header_len += + (tcp_header == NULL? 0: tcp_header->HdrLength*sizeof(UINT32)); break; case IPPROTO_UDP: udp_header = (PWINDIVERT_UDPHDR)NdisGetDataBuffer(buffer, sizeof(WINDIVERT_UDPHDR), NULL, 1, 0); - header_len = ip_header_len + sizeof(WINDIVERT_UDPHDR); + header_len += (udp_header == NULL? 0: sizeof(WINDIVERT_UDPHDR)); break; default: - header_len = ip_header_len; break; }