Add code to check boot option variable before use it

Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ni Ruiyu <ruiyu.ni@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13203 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
ydong10 2012-04-19 09:57:11 +00:00
parent a7450323c2
commit 8c08a567c6
3 changed files with 136 additions and 18 deletions

View File

@ -1238,6 +1238,13 @@ BdsLibDeleteOptionFromHandle (
return EFI_OUT_OF_RESOURCES;
}
if (!ValidateOption(BootOptionVar, BootOptionSize)) {
BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize);
FreePool (BootOptionVar);
Index++;
continue;
}
TempPtr = BootOptionVar;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
TempPtr += StrSize ((CHAR16 *) TempPtr);
@ -1300,10 +1307,14 @@ BdsDeleteAllInvalidEfiBootOption (
EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath;
UINT8 *TempPtr;
CHAR16 *Description;
BOOLEAN Corrupted;
Status = EFI_SUCCESS;
BootOrder = NULL;
BootOrderSize = 0;
Status = EFI_SUCCESS;
BootOrder = NULL;
Description = NULL;
OptionDevicePath = NULL;
BootOrderSize = 0;
Corrupted = FALSE;
//
// Check "BootOrder" variable firstly, this variable hold the number of boot options
@ -1330,23 +1341,27 @@ BdsDeleteAllInvalidEfiBootOption (
return EFI_OUT_OF_RESOURCES;
}
TempPtr = BootOptionVar;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
Description = (CHAR16 *) TempPtr;
TempPtr += StrSize ((CHAR16 *) TempPtr);
OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
if (!ValidateOption(BootOptionVar, BootOptionSize)) {
Corrupted = TRUE;
} else {
TempPtr = BootOptionVar;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
Description = (CHAR16 *) TempPtr;
TempPtr += StrSize ((CHAR16 *) TempPtr);
OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
//
// Skip legacy boot option (BBS boot device)
//
if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&
(DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {
FreePool (BootOptionVar);
Index++;
continue;
//
// Skip legacy boot option (BBS boot device)
//
if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) &&
(DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) {
FreePool (BootOptionVar);
Index++;
continue;
}
}
if (!BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) {
if (Corrupted || !BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) {
//
// Delete this invalid boot option "Boot####"
//
@ -1361,6 +1376,7 @@ BdsDeleteAllInvalidEfiBootOption (
// Mark this boot option in boot order as deleted
//
BootOrder[Index] = 0xffff;
Corrupted = FALSE;
}
FreePool (BootOptionVar);

View File

@ -257,6 +257,14 @@ BdsLibRegisterNewOption (
if (OptionPtr == NULL) {
continue;
}
//
// Validate the variable.
//
if (!ValidateOption(OptionPtr, OptionSize)) {
continue;
}
TempPtr = OptionPtr;
TempPtr += sizeof (UINT32) + sizeof (UINT16);
Description = (CHAR16 *) TempPtr;
@ -425,7 +433,7 @@ GetDevicePathSizeEx (
Size = 0;
while (!IsDevicePathEnd (DevicePath)) {
NodeSize = DevicePathNodeLength (DevicePath);
if (NodeSize == 0) {
if (NodeSize < END_DEVICE_PATH_LENGTH) {
return 0;
}
Size += NodeSize;
@ -480,6 +488,76 @@ StrSizeEx (
return (Length + 1) * sizeof (*String);
}
/**
Validate the EFI Boot#### variable (VendorGuid/Name)
@param Variable Boot#### variable data.
@param VariableSize Returns the size of the EFI variable that was read
@retval TRUE The variable data is correct.
@retval FALSE The variable data is corrupted.
**/
BOOLEAN
ValidateOption (
UINT8 *Variable,
UINTN VariableSize
)
{
UINT16 FilePathSize;
UINT8 *TempPtr;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempPath;
UINTN TempSize;
//
// Skip the option attribute
//
TempPtr = Variable;
TempPtr += sizeof (UINT32);
//
// Get the option's device path size
//
FilePathSize = *(UINT16 *) TempPtr;
TempPtr += sizeof (UINT16);
//
// Get the option's description string size
//
TempSize = StrSizeEx ((CHAR16 *) TempPtr, VariableSize);
TempPtr += TempSize;
//
// Get the option's device path
//
DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr;
TempPtr += FilePathSize;
//
// Validation boot option variable.
//
if ((FilePathSize == 0) || (TempSize == 0)) {
return FALSE;
}
if (TempSize + FilePathSize + sizeof (UINT16) + sizeof (UINT16) > VariableSize) {
return FALSE;
}
TempPath = DevicePath;
while (FilePathSize > 0) {
TempSize = GetDevicePathSizeEx (TempPath, FilePathSize);
if (TempSize == 0) {
return FALSE;
}
FilePathSize = (UINT16) (FilePathSize - TempSize);
TempPath += TempSize;
}
return TRUE;
}
/**
Convert a single character to number.
It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F'
@ -548,6 +626,14 @@ BdsLibVariableToOption (
if (Variable == NULL) {
return NULL;
}
//
// Validate Boot#### variable data.
//
if (!ValidateOption(Variable, VariableSize)) {
return NULL;
}
//
// Notes: careful defined the variable of Boot#### or
// Driver####, consider use some macro to abstract the code

View File

@ -126,4 +126,20 @@ BdsSetMemoryTypeInformationVariable (
VOID
);
/**
Validate the EFI Boot#### or Driver#### variable (VendorGuid/Name)
@param Variable Boot#### variable data.
@param VariableSize Returns the size of the EFI variable that was read
@retval TRUE The variable data is correct.
@retval FALSE The variable data is corrupted.
**/
BOOLEAN
ValidateOption (
UINT8 *Variable,
UINTN VariableSize
);
#endif // _BDS_LIB_H_