]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Add check when get boot option variable to avoid system hang.
authorydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 12 Jan 2012 05:32:59 +0000 (05:32 +0000)
committerydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524>
Thu, 12 Jan 2012 05:32:59 +0000 (05:32 +0000)
Signed-off-by: ydong10
Reviewed-by: niruiyu
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12927 6f19259b-4bc3-4df7-8a09-765794883524

IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c

index 68ddfc334f3b87cc2c0c4b59a14952392d4a4976..881f4dc0025226937fa0bd3afa925ad8213370fa 100644 (file)
@@ -390,6 +390,95 @@ BdsLibRegisterNewOption (
   return Status;\r
 }\r
 \r
+/**\r
+  Returns the size of a device path in bytes.\r
+\r
+  This function returns the size, in bytes, of the device path data structure \r
+  specified by DevicePath including the end of device path node. If DevicePath \r
+  is NULL, then 0 is returned. If the length of the device path is bigger than\r
+  MaxSize, also return 0 to indicate this is an invalidate device path.\r
+\r
+  @param  DevicePath         A pointer to a device path data structure.\r
+  @param  MaxSize            Max valid device path size. If big than this size, \r
+                             return error.\r
+  \r
+  @retval 0                  An invalid device path.\r
+  @retval Others             The size of a device path in bytes.\r
+\r
+**/\r
+UINTN\r
+GetDevicePathSizeEx (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
+  IN UINTN                           MaxSize\r
+  )\r
+{\r
+  UINTN  Size;\r
+  UINTN  NodeSize;\r
+\r
+  if (DevicePath == NULL) {\r
+    return 0;\r
+  }\r
+\r
+  //\r
+  // Search for the end of the device path structure\r
+  //\r
+  Size = 0;\r
+  while (!IsDevicePathEnd (DevicePath)) {\r
+    NodeSize = DevicePathNodeLength (DevicePath);\r
+    if (NodeSize == 0) {\r
+      return 0;\r
+    }\r
+    Size += NodeSize;\r
+    if (Size > MaxSize) {\r
+      return 0;\r
+    }\r
+    DevicePath = NextDevicePathNode (DevicePath);\r
+  }\r
+  Size += DevicePathNodeLength (DevicePath);\r
+  if (Size > MaxSize) {\r
+    return 0;\r
+  }\r
+\r
+  return Size;\r
+}\r
+\r
+/**\r
+  Returns the length of a Null-terminated Unicode string. If the length is \r
+  bigger than MaxStringLen, return length 0 to indicate that this is an \r
+  invalidate string.\r
+\r
+  This function returns the number of Unicode characters in the Null-terminated\r
+  Unicode string specified by String. \r
+\r
+  If String is NULL, then ASSERT().\r
+  If String is not aligned on a 16-bit boundary, then ASSERT().\r
+\r
+  @param  String           A pointer to a Null-terminated Unicode string.\r
+  @param  MaxStringLen     Max string len in this string.\r
+\r
+  @retval 0                An invalid string.\r
+  @retval Others           The length of String.\r
+\r
+**/\r
+UINTN\r
+StrSizeEx (\r
+  IN      CONST CHAR16              *String,\r
+  IN      UINTN                     MaxStringLen\r
+  )\r
+{\r
+  UINTN                             Length;\r
+\r
+  ASSERT (String != NULL && MaxStringLen != 0);\r
+  ASSERT (((UINTN) String & BIT0) == 0);\r
+\r
+  for (Length = 0; *String != L'\0' && MaxStringLen != Length; String++, Length++);\r
+\r
+  if (*String != L'\0' && MaxStringLen == Length) {\r
+    return 0;\r
+  }\r
+\r
+  return (Length + 1) * sizeof (*String);\r
+}\r
 \r
 /**\r
   Build the boot#### or driver#### option from the VariableName, the\r
@@ -417,11 +506,13 @@ BdsLibVariableToOption (
   UINT8                     *TempPtr;\r
   UINTN                     VariableSize;\r
   EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *TempPath;\r
   BDS_COMMON_OPTION         *Option;\r
   VOID                      *LoadOptions;\r
   UINT32                    LoadOptionsSize;\r
   CHAR16                    *Description;\r
   UINT8                     NumOff;\r
+  UINTN                     TempSize;\r
   //\r
   // Read the variable. We will never free this data.\r
   //\r
@@ -458,7 +549,11 @@ BdsLibVariableToOption (
   //\r
   // Get the option's description string size\r
   //\r
-  TempPtr     += StrSize ((CHAR16 *) TempPtr);\r
+  TempSize = StrSizeEx ((CHAR16 *) TempPtr, VariableSize);\r
+  if (TempSize == 0) {\r
+    return NULL;\r
+  }\r
+  TempPtr += TempSize;\r
 \r
   //\r
   // Get the option's device path\r
@@ -466,7 +561,26 @@ BdsLibVariableToOption (
   DevicePath =  (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;\r
   TempPtr    += FilePathSize;\r
 \r
+  //\r
+  // Validation device path.\r
+  //\r
+  TempPath       = DevicePath;\r
+  while (FilePathSize > 0) {\r
+    TempSize = GetDevicePathSizeEx (TempPath, FilePathSize);\r
+    if (TempSize == 0) {\r
+      return NULL;\r
+    }\r
+    FilePathSize = (UINT16) (FilePathSize - TempSize);\r
+    TempPath    += TempSize;\r
+  }\r
+\r
+  //\r
+  // Get load opion data.\r
+  //\r
   LoadOptions     = TempPtr;\r
+  if (VariableSize < (UINTN)(TempPtr - Variable)) {\r
+    return NULL;\r
+  }\r
   LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable));\r
 \r
   //\r