]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c
MdeModulePkg:Fix a robustness issue of Mnp Driver
[mirror_edk2.git] / MdeModulePkg / Universal / Network / MnpDxe / MnpVlan.c
index 6e14c1f37f3f8b07dfc850e36e62b5bdaf6ad386..98cbc2e35da85c906f15c8d1ec29429b72f7063f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   VLAN Config Protocol implementation and VLAN packet process routine.\r
 \r
-Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions\r
 of the BSD License which accompanies this distribution.  The full\r
@@ -230,6 +230,59 @@ MnpInsertVlanTag (
   VlanTci->Uint16        = HTONS (VlanTci->Uint16);\r
 }\r
 \r
+/**\r
+  Check VLAN configuration variable and delete the duplicative content if has identical Vlan ID.\r
+\r
+  @param[in]      MnpDeviceData      Pointer to the MNP device context data.\r
+  @param[in]      Buffer             Pointer to the buffer contains the array of VLAN_TCI.\r
+  @param[in]      NumberOfVlan       Pointer to number of VLAN.\r
+  @param[out]     NewNumberOfVlan    Pointer to number of unique VLAN.\r
+  \r
+  @retval EFI_SUCCESS            The VLAN variable is successfully checked.\r
+  @retval EFI_OUT_OF_RESOURCES   There is not enough resource to set the configuration.\r
+\r
+**/\r
+EFI_STATUS\r
+MnpCheckVlanVariable (\r
+  IN     MNP_DEVICE_DATA   *MnpDeviceData,\r
+  IN     VLAN_TCI          *Buffer,\r
+  IN     UINTN             NumberOfVlan,\r
+     OUT UINTN             *NewNumberOfVlan\r
+  )\r
+{\r
+  UINTN             Index;\r
+  UINTN             Index2;\r
+  UINTN             Count;\r
+  BOOLEAN           FoundDuplicateItem;\r
+  EFI_STATUS        Status;\r
+\r
+  Count = 0;\r
+  FoundDuplicateItem  = FALSE;\r
+  Status = EFI_SUCCESS;\r
+  \r
+  for (Index = 0; Index < NumberOfVlan; Index++) {\r
+   for (Index2 = Index + 1; Index2 < NumberOfVlan; Index2++) {\r
+     if (Buffer[Index].Bits.Vid == Buffer[Index2].Bits.Vid) {\r
+       FoundDuplicateItem = TRUE;\r
+       Count++;\r
+       break;\r
+     }\r
+   }\r
+   if (FoundDuplicateItem) {\r
+    for (Index2 = Index +1; Index2 < NumberOfVlan; Index++, Index2++) {\r
+      CopyMem (Buffer + Index, Buffer + Index2, sizeof (VLAN_TCI));\r
+    }\r
+   }\r
+   FoundDuplicateItem = FALSE;\r
+  }\r
+\r
+  *NewNumberOfVlan = NumberOfVlan - Count;\r
+  if (Count != 0) {\r
+    Status = MnpSetVlanVariable (MnpDeviceData, *NewNumberOfVlan, Buffer);\r
+  }\r
+  \r
+  return Status;\r
+}\r
 \r
 /**\r
   Get VLAN configuration variable.\r
@@ -255,6 +308,7 @@ MnpGetVlanVariable (
   UINTN       BufferSize;\r
   EFI_STATUS  Status;\r
   VLAN_TCI    *Buffer;\r
+  UINTN       NewNumberOfVlan;\r
 \r
   //\r
   // Get VLAN configuration from EFI Variable\r
@@ -292,13 +346,15 @@ MnpGetVlanVariable (
     return Status;\r
   }\r
 \r
-  *NumberOfVlan = BufferSize / sizeof (VLAN_TCI);\r
-  *VlanVariable = Buffer;\r
+  Status = MnpCheckVlanVariable (MnpDeviceData, Buffer, BufferSize / sizeof (VLAN_TCI), &NewNumberOfVlan);\r
+  if (!EFI_ERROR (Status)) {\r
+    *NumberOfVlan = NewNumberOfVlan;\r
+    *VlanVariable = Buffer;\r
+  }\r
 \r
   return Status;\r
 }\r
 \r
-\r
 /**\r
   Set VLAN configuration variable.\r
 \r