]> git.proxmox.com Git - mirror_edk2.git/blobdiff - NetworkPkg/Ip6Dxe/Ip6Nd.c
NetworkPkg/Ip6Dxe: Improve Neightbor Discovery message validation.
[mirror_edk2.git] / NetworkPkg / Ip6Dxe / Ip6Nd.c
index be3dd911b6c5cf0b025d83f4e153eaa9709bd04c..fd7f60b2f92c01a036328ed56060ea801604ab2a 100644 (file)
@@ -1,15 +1,9 @@
 /** @file\r
   Implementation of Neighbor Discovery support routines.\r
 \r
-  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
 \r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -822,7 +816,7 @@ Ip6OnDADFinished (
   EFI_DHCP6_PACKET_OPTION   *Oro;\r
   EFI_DHCP6_RETRANSMISSION  InfoReqReXmit;\r
   EFI_IPv6_ADDRESS          AllNodes;\r
-  \r
+\r
   IpSb     = IpIf->Service;\r
   AddrInfo = DadEntry->AddressInfo;\r
 \r
@@ -853,9 +847,9 @@ Ip6OnDADFinished (
         // with DNS SERVERS.\r
         //\r
         Oro         = (EFI_DHCP6_PACKET_OPTION *) OptBuf;\r
-        Oro->OpCode = HTONS (IP6_CONFIG_DHCP6_OPTION_ORO);\r
+        Oro->OpCode = HTONS (DHCP6_OPT_ORO);\r
         Oro->OpLen  = HTONS (2);\r
-        *((UINT16 *) &Oro->Data[0]) = HTONS (IP6_CONFIG_DHCP6_OPTION_DNS_SERVERS);\r
+        *((UINT16 *) &Oro->Data[0]) = HTONS (DHCP6_OPT_DNS_SERVERS);\r
 \r
         InfoReqReXmit.Irt = 4;\r
         InfoReqReXmit.Mrc = 64;\r
@@ -988,7 +982,7 @@ Ip6InitDADProcess (
   if (Ip6FindDADEntry (IpIf->Service, &AddressInfo->Address, NULL) != NULL) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
+\r
   Status   = EFI_SUCCESS;\r
   IpSb     = IpIf->Service;\r
   DadXmits = &IpSb->Ip6ConfigInstance.DadXmits;\r
@@ -1651,7 +1645,7 @@ Ip6ProcessNeighborSolicit (
   //\r
   // Sends a Neighbor Advertisement as response.\r
   // Set the Router flag to zero since the node is a host.\r
-  // If the source address of the solicitation is unspeicifed, and target address\r
+  // If the source address of the solicitation is unspecified, and target address\r
   // is one of the maintained address, reply a unsolicited multicast advertisement.\r
   //\r
   if (IsDAD && IsMaintained) {\r
@@ -1933,7 +1927,7 @@ Ip6ProcessRouterAdvertise (
   UINT32                    ReachableTime;\r
   UINT32                    RetransTimer;\r
   UINT16                    RouterLifetime;\r
-  UINT16                    Offset;\r
+  UINT32                    Offset;\r
   UINT8                     Type;\r
   UINT8                     Length;\r
   IP6_ETHER_ADDR_OPTION     LinkLayerOption;\r
@@ -2093,17 +2087,18 @@ Ip6ProcessRouterAdvertise (
   }\r
 \r
   //\r
-  // If an valid router advertisment is received, stops router solicitation.\r
+  // If an valid router advertisement is received, stops router solicitation.\r
   //\r
   IpSb->RouterAdvertiseReceived = TRUE;\r
 \r
   //\r
   // The only defined options that may appear are the Source\r
   // Link-Layer Address, Prefix information and MTU options.\r
-  // All included options have a length that is greater than zero.\r
+  // All included options have a length that is greater than zero and\r
+  // fit within the input packet.\r
   //\r
   Offset = 16;\r
-  while (Offset < Head->PayloadLength) {\r
+  while (Offset < (UINT32) Head->PayloadLength) {\r
     NetbufCopy (Packet, Offset, sizeof (UINT8), &Type);\r
     switch (Type) {\r
     case Ip6OptionEtherSource:\r
@@ -2111,9 +2106,12 @@ Ip6ProcessRouterAdvertise (
       // Update the neighbor cache\r
       //\r
       NetbufCopy (Packet, Offset, sizeof (IP6_ETHER_ADDR_OPTION), (UINT8 *) &LinkLayerOption);\r
-      if (LinkLayerOption.Length <= 0) {\r
-        goto Exit;\r
-      }\r
+\r
+      //\r
+      // Option size validity ensured by Ip6IsNDOptionValid().\r
+      //\r
+      ASSERT (LinkLayerOption.Length != 0);\r
+      ASSERT (Offset + (UINT32) LinkLayerOption.Length * 8 >= (UINT32) Head->PayloadLength);\r
 \r
       ZeroMem (&LinkLayerAddress, sizeof (EFI_MAC_ADDRESS));\r
       CopyMem (&LinkLayerAddress, LinkLayerOption.EtherAddr, 6);\r
@@ -2157,13 +2155,17 @@ Ip6ProcessRouterAdvertise (
         }\r
       }\r
 \r
-      Offset = (UINT16) (Offset + (UINT16) LinkLayerOption.Length * 8);\r
+      Offset += (UINT32) LinkLayerOption.Length * 8;\r
       break;\r
     case Ip6OptionPrefixInfo:\r
       NetbufCopy (Packet, Offset, sizeof (IP6_PREFIX_INFO_OPTION), (UINT8 *) &PrefixOption);\r
-      if (PrefixOption.Length != 4) {\r
-        goto Exit;\r
-      }\r
+\r
+      //\r
+      // Option size validity ensured by Ip6IsNDOptionValid().\r
+      //\r
+      ASSERT (PrefixOption.Length == 4);\r
+      ASSERT (Offset + (UINT32) PrefixOption.Length * 8 >= (UINT32) Head->PayloadLength);\r
+\r
       PrefixOption.ValidLifetime     = NTOHL (PrefixOption.ValidLifetime);\r
       PrefixOption.PreferredLifetime = NTOHL (PrefixOption.PreferredLifetime);\r
 \r
@@ -2257,7 +2259,7 @@ Ip6ProcessRouterAdvertise (
           //\r
           if (!Ip6IsOneOfSetAddress (IpSb, &StatelessAddress, NULL, NULL)) {\r
             //\r
-            // And also not in the DAD process, check its uniqeness firstly.\r
+            // And also not in the DAD process, check its uniqueness firstly.\r
             //\r
             if (Ip6FindDADEntry (IpSb, &StatelessAddress, NULL) == NULL) {\r
               Status = Ip6SetAddress (\r
@@ -2309,7 +2311,7 @@ Ip6ProcessRouterAdvertise (
 \r
           } else if (PrefixList->ValidLifetime <= 7200) {\r
             //\r
-            // If RemainingLifetime is less than or equls to 2 hours, ignore the\r
+            // If RemainingLifetime is less than or equals to 2 hours, ignore the\r
             // Prefix Information option with regards to the valid lifetime.\r
             // TODO: If this option has been authenticated, set the valid lifetime.\r
             //\r
@@ -2327,9 +2329,12 @@ Ip6ProcessRouterAdvertise (
       break;\r
     case Ip6OptionMtu:\r
       NetbufCopy (Packet, Offset, sizeof (IP6_MTU_OPTION), (UINT8 *) &MTUOption);\r
-      if (MTUOption.Length != 1) {\r
-        goto Exit;\r
-      }\r
+\r
+      //\r
+      // Option size validity ensured by Ip6IsNDOptionValid().\r
+      //\r
+      ASSERT (MTUOption.Length == 1);\r
+      ASSERT (Offset + (UINT32) MTUOption.Length * 8 >= (UINT32) Head->PayloadLength);\r
 \r
       //\r
       // Use IPv6 minimum link MTU 1280 bytes as the maximum packet size in order\r
@@ -2344,11 +2349,10 @@ Ip6ProcessRouterAdvertise (
       // Silently ignore unrecognized options\r
       //\r
       NetbufCopy (Packet, Offset + sizeof (UINT8), sizeof (UINT8), &Length);\r
-      if (Length <= 0) {\r
-        goto Exit;\r
-      }\r
 \r
-      Offset = (UINT16) (Offset + (UINT16) Length * 8);\r
+      ASSERT (Length != 0);\r
+\r
+      Offset += (UINT32) Length * 8;\r
       break;\r
     }\r
   }\r
@@ -2371,7 +2375,7 @@ Exit:
                                  the IP head removed.\r
 \r
   @retval EFI_INVALID_PARAMETER  The parameter is invalid.\r
-  @retval EFI_OUT_OF_RESOURCES   Insuffcient resources to complete the\r
+  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to complete the\r
                                  operation.\r
   @retval EFI_SUCCESS            Successfully updated the route caches.\r
 \r
@@ -3075,7 +3079,7 @@ Ip6NdFasterTimerTicking (
 \r
 /**\r
   The heartbeat timer of ND module in 1 second. This time routine handles following\r
-  things: 1) maitain default router list; 2) maintain prefix options;\r
+  things: 1) maintain default router list; 2) maintain prefix options;\r
   3) maintain route caches.\r
 \r
   @param[in]  IpSb              The IP6 service binding instance.\r