17
17
@param[in] IpSb The IP6 service data.
18
18
@param[in] Packet The to be validated packet.
19
19
@param[in] Option The first byte of the option.
20
- @param[in] OptionLen The length of the whole option.
20
+ @param[in] OptionLen The length of all options, expressed in byte length of octets.
21
+ Maximum length is 2046 bytes or ((n + 1) * 8) - 2 where n is 255.
21
22
@param[in] Pointer Identifies the octet offset within
22
23
the invoking packet where the error was detected.
23
24
@@ -31,12 +32,33 @@ Ip6IsOptionValid (
31
32
IN IP6_SERVICE * IpSb ,
32
33
IN NET_BUF * Packet ,
33
34
IN UINT8 * Option ,
34
- IN UINT8 OptionLen ,
35
+ IN UINT16 OptionLen ,
35
36
IN UINT32 Pointer
36
37
)
37
38
{
38
- UINT8 Offset ;
39
- UINT8 OptionType ;
39
+ UINT16 Offset ;
40
+ UINT8 OptionType ;
41
+ UINT8 OptDataLen ;
42
+
43
+ if (Option == NULL ) {
44
+ ASSERT (Option != NULL );
45
+ return FALSE;
46
+ }
47
+
48
+ if ((OptionLen <= 0 ) || (OptionLen > IP6_MAX_EXT_DATA_LENGTH )) {
49
+ ASSERT (OptionLen > 0 && OptionLen <= IP6_MAX_EXT_DATA_LENGTH );
50
+ return FALSE;
51
+ }
52
+
53
+ if (Packet == NULL ) {
54
+ ASSERT (Packet != NULL );
55
+ return FALSE;
56
+ }
57
+
58
+ if (IpSb == NULL ) {
59
+ ASSERT (IpSb != NULL );
60
+ return FALSE;
61
+ }
40
62
41
63
Offset = 0 ;
42
64
@@ -54,7 +76,8 @@ Ip6IsOptionValid (
54
76
//
55
77
// It is a PadN option
56
78
//
57
- Offset = (UINT8 )(Offset + * (Option + Offset + 1 ) + 2 );
79
+ OptDataLen = ((IP6_OPTION_HEADER * )(Option + Offset ))-> Length ;
80
+ Offset = IP6_NEXT_OPTION_OFFSET (Offset , OptDataLen );
58
81
break ;
59
82
case Ip6OptionRouterAlert :
60
83
//
@@ -69,7 +92,8 @@ Ip6IsOptionValid (
69
92
//
70
93
switch (OptionType & Ip6OptionMask ) {
71
94
case Ip6OptionSkip :
72
- Offset = (UINT8 )(Offset + * (Option + Offset + 1 ));
95
+ OptDataLen = ((IP6_OPTION_HEADER * )(Option + Offset ))-> Length ;
96
+ Offset = IP6_NEXT_OPTION_OFFSET (Offset , OptDataLen );
73
97
break ;
74
98
case Ip6OptionDiscard :
75
99
return FALSE;
@@ -308,7 +332,7 @@ Ip6IsExtsValid (
308
332
UINT32 Pointer ;
309
333
UINT32 Offset ;
310
334
UINT8 * Option ;
311
- UINT8 OptionLen ;
335
+ UINT16 OptionLen ;
312
336
BOOLEAN Flag ;
313
337
UINT8 CountD ;
314
338
UINT8 CountA ;
@@ -385,6 +409,36 @@ Ip6IsExtsValid (
385
409
// Fall through
386
410
//
387
411
case IP6_DESTINATION :
412
+ //
413
+ // See https://www.rfc-editor.org/rfc/rfc2460#section-4.2 page 23
414
+ //
415
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
416
+ // | Next Header | Hdr Ext Len | |
417
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
418
+ // | |
419
+ // . .
420
+ // . Options .
421
+ // . .
422
+ // | |
423
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
424
+ //
425
+ //
426
+ // Next Header 8-bit selector. Identifies the type of header
427
+ // immediately following the Destination Options
428
+ // header. Uses the same values as the IPv4
429
+ // Protocol field [RFC-1700 et seq.].
430
+ //
431
+ // Hdr Ext Len 8-bit unsigned integer. Length of the
432
+ // Destination Options header in 8-octet units, not
433
+ // including the first 8 octets.
434
+ //
435
+ // Options Variable-length field, of length such that the
436
+ // complete Destination Options header is an
437
+ // integer multiple of 8 octets long. Contains one
438
+ // or more TLV-encoded options, as described in
439
+ // section 4.2.
440
+ //
441
+
388
442
if (* NextHeader == IP6_DESTINATION ) {
389
443
CountD ++ ;
390
444
}
@@ -398,7 +452,7 @@ Ip6IsExtsValid (
398
452
399
453
Offset ++ ;
400
454
Option = ExtHdrs + Offset ;
401
- OptionLen = ( UINT8 )(( * Option + 1 ) * 8 - 2 );
455
+ OptionLen = IP6_HDR_EXT_LEN ( * Option ) - sizeof ( IP6_EXT_HDR );
402
456
Option ++ ;
403
457
Offset ++ ;
404
458
@@ -430,7 +484,7 @@ Ip6IsExtsValid (
430
484
//
431
485
// Ignore the routing header and proceed to process the next header.
432
486
//
433
- Offset = Offset + (RoutingHead -> HeaderLen + 1 ) * 8 ;
487
+ Offset = Offset + IP6_HDR_EXT_LEN (RoutingHead -> HeaderLen ) ;
434
488
435
489
if (UnFragmentLen != NULL ) {
436
490
* UnFragmentLen = Offset ;
@@ -441,7 +495,7 @@ Ip6IsExtsValid (
441
495
// to the packet's source address, pointing to the unrecognized routing
442
496
// type.
443
497
//
444
- Pointer = Offset + 2 + sizeof (EFI_IP6_HEADER );
498
+ Pointer = Offset + sizeof ( IP6_EXT_HDR ) + sizeof (EFI_IP6_HEADER );
445
499
if ((IpSb != NULL ) && (Packet != NULL ) &&
446
500
!IP6_IS_MULTICAST (& Packet -> Ip .Ip6 -> DestinationAddress ))
447
501
{
@@ -527,7 +581,7 @@ Ip6IsExtsValid (
527
581
//
528
582
// RFC2402, Payload length is specified in 32-bit words, minus "2".
529
583
//
530
- OptionLen = (UINT8 )( (* Option + 2 ) * 4 );
584
+ OptionLen = (( UINT16 ) (* Option + 2 ) * 4 );
531
585
Offset = Offset + OptionLen ;
532
586
break ;
533
587
0 commit comments