Add check when get boot option variable to avoid system hang.

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
This commit is contained in:
ydong10 2012-01-12 05:32:59 +00:00
parent f79fa76e9c
commit b16cc38bf3
1 changed files with 115 additions and 1 deletions

View File

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