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
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
//\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
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