diff options
author | ydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-01-12 05:32:59 +0000 |
---|---|---|
committer | ydong10 <ydong10@6f19259b-4bc3-4df7-8a09-765794883524> | 2012-01-12 05:32:59 +0000 |
commit | b16cc38bf3d74e7b781022aad96f28b3f8507fdd (patch) | |
tree | ce18dc75fada9c3e1c7d068ccc2111d853bf4d79 /IntelFrameworkModulePkg | |
parent | f79fa76e9ccebb8cb680455e034f63035ae44412 (diff) | |
download | edk2-b16cc38bf3d74e7b781022aad96f28b3f8507fdd.tar.gz edk2-b16cc38bf3d74e7b781022aad96f28b3f8507fdd.tar.bz2 edk2-b16cc38bf3d74e7b781022aad96f28b3f8507fdd.zip |
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
Diffstat (limited to 'IntelFrameworkModulePkg')
-rw-r--r-- | IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c | 116 |
1 files changed, 115 insertions, 1 deletions
diff --git a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c index 68ddfc334f..881f4dc002 100644 --- a/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c +++ b/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c @@ -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));
//
|