@@ -2168,6 +2168,7 @@ static void windivert_read_service_request(context_t context, packet_t packet,
2168
2168
addr [i ].TCPChecksum = packet -> tcp_checksum ;
2169
2169
addr [i ].UDPChecksum = packet -> udp_checksum ;
2170
2170
addr [i ].Reserved1 = 0 ;
2171
+ addr [i ].Reserved2 = 0 ;
2171
2172
layer_data = (PVOID )packet -> data ;
2172
2173
switch (packet -> layer )
2173
2174
{
@@ -2371,6 +2372,7 @@ static void windivert_fast_read_service_request(PVOID packet, ULONG packet_len,
2371
2372
addr -> TCPChecksum = (tcp_checksum ? 1 : 0 );
2372
2373
addr -> UDPChecksum = (udp_checksum ? 1 : 0 );
2373
2374
addr -> Reserved1 = 0 ;
2375
+ addr -> Reserved2 = 0 ;
2374
2376
switch (layer )
2375
2377
{
2376
2378
case WINDIVERT_LAYER_NETWORK :
@@ -4180,7 +4182,7 @@ static void windivert_resource_assignment_v4_classify(
4180
4182
4181
4183
windivert_socket_classify (context , & socket_data ,
4182
4184
/*event=*/ WINDIVERT_EVENT_SOCKET_BIND , /*ipv4=*/ TRUE,
4183
- /*outbound=*/ FALSE , loopback , result );
4185
+ /*outbound=*/ TRUE , loopback , result );
4184
4186
}
4185
4187
4186
4188
/*
@@ -4223,7 +4225,7 @@ static void windivert_resource_assignment_v6_classify(
4223
4225
4224
4226
windivert_socket_classify (context , & socket_data ,
4225
4227
/*event=*/ WINDIVERT_EVENT_SOCKET_BIND , /*ipv4=*/ FALSE,
4226
- /*outbound=*/ FALSE , loopback , result );
4228
+ /*outbound=*/ TRUE , loopback , result );
4227
4229
}
4228
4230
4229
4231
/*
@@ -4261,7 +4263,7 @@ static void windivert_resource_release_v4_classify(
4261
4263
4262
4264
windivert_socket_classify (context , & socket_data ,
4263
4265
/*event=*/ WINDIVERT_EVENT_SOCKET_CLOSE , /*ipv4=*/ TRUE,
4264
- /*outbound=*/ FALSE , loopback , result );
4266
+ /*outbound=*/ TRUE , loopback , result );
4265
4267
}
4266
4268
4267
4269
/*
@@ -4299,7 +4301,7 @@ static void windivert_resource_release_v6_classify(
4299
4301
4300
4302
windivert_socket_classify (context , & socket_data ,
4301
4303
/*event=*/ WINDIVERT_EVENT_SOCKET_CLOSE , /*ipv4=*/ FALSE,
4302
- /*outbound=*/ FALSE , loopback , result );
4304
+ /*outbound=*/ TRUE , loopback , result );
4303
4305
}
4304
4306
4305
4307
/*
@@ -4527,7 +4529,7 @@ static void windivert_auth_listen_v4_classify(
4527
4529
4528
4530
windivert_socket_classify (context , & socket_data ,
4529
4531
/*event=*/ WINDIVERT_EVENT_SOCKET_LISTEN , /*ipv4=*/ TRUE,
4530
- /*outbound=*/ FALSE , loopback , result );
4532
+ /*outbound=*/ TRUE , loopback , result );
4531
4533
}
4532
4534
4533
4535
/*
@@ -4569,7 +4571,7 @@ static void windivert_auth_listen_v6_classify(
4569
4571
4570
4572
windivert_socket_classify (context , & socket_data ,
4571
4573
/*event=*/ WINDIVERT_EVENT_SOCKET_LISTEN , /*ipv4=*/ FALSE,
4572
- /*outbound=*/ FALSE , loopback , result );
4574
+ /*outbound=*/ TRUE , loopback , result );
4573
4575
}
4574
4576
4575
4577
/*
@@ -5289,7 +5291,7 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5289
5291
PWINDIVERT_UDPHDR * udp_header_ptr , UINT8 * proto_ptr , UINT * header_len_ptr ,
5290
5292
UINT * payload_len_ptr )
5291
5293
{
5292
- UINT tot_len , ip_header_len ;
5294
+ UINT total_len , ip_header_len = 0 ;
5293
5295
PWINDIVERT_IPHDR ip_header = NULL ;
5294
5296
PWINDIVERT_IPV6HDR ipv6_header = NULL ;
5295
5297
PWINDIVERT_ICMPHDR icmp_header = NULL ;
@@ -5306,8 +5308,8 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5306
5308
DEBUG ("FILTER: REJECT (packet is NULL)" );
5307
5309
return FALSE;
5308
5310
}
5309
- tot_len = NET_BUFFER_DATA_LENGTH (buffer );
5310
- if (tot_len < sizeof (WINDIVERT_IPHDR ))
5311
+ total_len = NET_BUFFER_DATA_LENGTH (buffer );
5312
+ if (total_len < sizeof (WINDIVERT_IPHDR ))
5311
5313
{
5312
5314
DEBUG ("FILTER: REJECT (packet length too small)" );
5313
5315
return FALSE;
@@ -5317,7 +5319,7 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5317
5319
if (ipv4 )
5318
5320
{
5319
5321
// IPv4:
5320
- if (tot_len < sizeof (WINDIVERT_IPHDR ))
5322
+ if (total_len < sizeof (WINDIVERT_IPHDR ))
5321
5323
{
5322
5324
DEBUG ("FILTER: REJECT (packet length too small)" );
5323
5325
return FALSE;
@@ -5331,14 +5333,14 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5331
5333
}
5332
5334
ip_header_len = ip_header -> HdrLength * sizeof (UINT32 );
5333
5335
if (ip_header -> Version != 4 ||
5334
- RtlUshortByteSwap (ip_header -> Length ) != tot_len ||
5336
+ RtlUshortByteSwap (ip_header -> Length ) != total_len ||
5335
5337
ip_header -> HdrLength < 5 ||
5336
- ip_header_len > tot_len )
5338
+ ip_header_len > total_len )
5337
5339
{
5338
5340
DEBUG ("FILTER: REJECT (bad IPv4 packet)" );
5339
5341
return FALSE;
5340
5342
}
5341
- if (!frag_mode &&
5343
+ if (!frag_mode &&
5342
5344
(WINDIVERT_IPHDR_GET_MF (ip_header ) != 0 ||
5343
5345
WINDIVERT_IPHDR_GET_FRAGOFF (ip_header ) != 0 ))
5344
5346
{
@@ -5351,7 +5353,7 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5351
5353
else
5352
5354
{
5353
5355
// IPv6:
5354
- if (tot_len < sizeof (WINDIVERT_IPV6HDR ))
5356
+ if (total_len < sizeof (WINDIVERT_IPV6HDR ))
5355
5357
{
5356
5358
DEBUG ("FILTER: REJECT (packet length too small)" );
5357
5359
return FALSE;
@@ -5365,9 +5367,9 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5365
5367
}
5366
5368
ip_header_len = sizeof (WINDIVERT_IPV6HDR );
5367
5369
if (ipv6_header -> Version != 6 ||
5368
- ip_header_len > tot_len ||
5370
+ ip_header_len > total_len ||
5369
5371
RtlUshortByteSwap (ipv6_header -> Length ) +
5370
- sizeof (WINDIVERT_IPV6HDR ) != tot_len )
5372
+ sizeof (WINDIVERT_IPV6HDR ) != total_len )
5371
5373
{
5372
5374
DEBUG ("FILTER: REJECT (bad IPv6 packet)" );
5373
5375
return FALSE;
@@ -5395,6 +5397,8 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5395
5397
if (!frag_mode )
5396
5398
{
5397
5399
DEBUG ("FILTER: REJECT (fragment)" );
5400
+ NdisRetreatNetBufferDataStart (buffer , ip_header_len ,
5401
+ 0 , NULL );
5398
5402
return FALSE;
5399
5403
}
5400
5404
ext_header_len = 8 ;
@@ -5420,6 +5424,13 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5420
5424
}
5421
5425
5422
5426
proto = ext_header [0 ];
5427
+ if (ip_header_len + ext_header_len > total_len )
5428
+ {
5429
+ DEBUG ("FILTER: REJECT (bad IPv6 extension header)" );
5430
+ NdisRetreatNetBufferDataStart (buffer , ip_header_len ,
5431
+ 0 , NULL );
5432
+ return FALSE;
5433
+ }
5423
5434
ip_header_len += ext_header_len ;
5424
5435
NdisAdvanceNetBufferDataStart (buffer , ext_header_len , FALSE,
5425
5436
NULL );
@@ -5443,8 +5454,17 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5443
5454
case IPPROTO_TCP :
5444
5455
tcp_header = (PWINDIVERT_TCPHDR )NdisGetDataBuffer (buffer ,
5445
5456
sizeof (WINDIVERT_TCPHDR ), NULL , 1 , 0 );
5446
- header_len +=
5447
- (tcp_header == NULL ? 0 : tcp_header -> HdrLength * sizeof (UINT32 ));
5457
+ if (tcp_header != NULL )
5458
+ {
5459
+ UINT tcp_header_len = tcp_header -> HdrLength * sizeof (UINT32 );
5460
+ if (header_len + tcp_header_len > total_len )
5461
+ {
5462
+ // Bad TCP options:
5463
+ tcp_header = NULL ;
5464
+ break ;
5465
+ }
5466
+ header_len += tcp_header_len ;
5467
+ }
5448
5468
break ;
5449
5469
case IPPROTO_UDP :
5450
5470
udp_header = (PWINDIVERT_UDPHDR )NdisGetDataBuffer (buffer ,
@@ -5454,7 +5474,6 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5454
5474
default :
5455
5475
break ;
5456
5476
}
5457
-
5458
5477
status = NdisRetreatNetBufferDataStart (buffer , ip_header_len , 0 , NULL );
5459
5478
if (!NT_SUCCESS (status ))
5460
5479
{
@@ -5471,7 +5490,7 @@ static BOOL windivert_parse_headers(PNET_BUFFER buffer, BOOL ipv4,
5471
5490
* udp_header_ptr = udp_header ;
5472
5491
* proto_ptr = proto ;
5473
5492
* header_len_ptr = header_len ;
5474
- * payload_len_ptr = ( header_len > tot_len ? 0 : tot_len - header_len ) ;
5493
+ * payload_len_ptr = total_len - header_len ;
5475
5494
5476
5495
return TRUE;
5477
5496
}
0 commit comments