VariableServiceSetVariable() should also check authenticate data to avoid buffer overflow,\r
integer overflow. It should also check attribute to avoid authentication bypass.\r
\r
-Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
///\r
BOOLEAN mEnableLocking = TRUE;\r
\r
-//\r
-// To prevent name collisions with possible future globally defined variables,\r
-// other internal firmware data variables that are not defined here must be\r
-// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or\r
-// any other GUID defined by the UEFI Specification. Implementations must\r
-// only permit the creation of variables with a UEFI Specification-defined\r
-// VendorGuid when these variables are documented in the UEFI Specification.\r
-//\r
-GLOBAL_VARIABLE_ENTRY mGlobalVariableList[] = {\r
- {EFI_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_TIME_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_PLATFORM_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_PLATFORM_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_CON_IN_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_CON_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_ERR_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_CON_IN_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_CON_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_ERR_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_BOOT_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_BOOT_NEXT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_BOOT_CURRENT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_DRIVER_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_SETUP_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_KEY_EXCHANGE_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT},\r
- {EFI_PLATFORM_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT},\r
- {EFI_SIGNATURE_SUPPORT_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_SECURE_BOOT_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_KEK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_PK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_DB_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_DBX_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_DBT_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
- {EFI_OS_INDICATIONS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {EFI_VENDOR_KEYS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT},\r
-};\r
-GLOBAL_VARIABLE_ENTRY mGlobalVariableList2[] = {\r
- {L"Boot####", VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {L"Driver####", VARIABLE_ATTRIBUTE_NV_BS_RT},\r
- {L"Key####", VARIABLE_ATTRIBUTE_NV_BS_RT},\r
-};\r
-\r
/**\r
\r
SecureBoot Hook for auth variable update.\r
HwErrVariableTotalSize += VariableSize;\r
} else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
CommonVariableTotalSize += VariableSize;\r
+ }\r
}\r
- }\r
Variable = NextVariable;\r
}\r
\r
HwErrVariableTotalSize += VariableSize;\r
} else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
CommonVariableTotalSize += VariableSize;\r
+ }\r
}\r
- }\r
Variable = NextVariable;\r
}\r
\r
HwErrVariableTotalSize += VariableSize;\r
} else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) {\r
CommonVariableTotalSize += VariableSize;\r
+ }\r
}\r
}\r
- }\r
\r
Variable = NextVariable;\r
}\r
HwErrVariableTotalSize += NewVariableSize;\r
} else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
CommonVariableTotalSize += NewVariableSize;\r
- }\r
+ }\r
if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) ||\r
(CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) {\r
//\r
mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize);\r
} else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) {\r
mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize);\r
- }\r
+ }\r
\r
NextVariable = GetNextVariablePtr (NextVariable);\r
}\r
}\r
UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE);\r
FlushHobVariableToFlash (VariableName, VendorGuid);\r
- }\r
+ }\r
goto Done;\r
}\r
//\r
mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize);\r
} else {\r
mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize);\r
- }\r
+ }\r
//\r
// update the memory copy of Flash region.\r
//\r
return TRUE;\r
}\r
\r
-/**\r
- This code checks if variable guid is global variable guid first.\r
- If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2 and attributes matched.\r
-\r
- @param[in] VariableName Pointer to variable name.\r
- @param[in] VendorGuid Variable Vendor Guid.\r
- @param[in] Attributes Attributes of the variable.\r
-\r
- @retval EFI_SUCCESS Variable is not global variable, or Variable is global variable, variable name is in the lists and attributes matched.\r
- @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists or attributes unmatched.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-CheckEfiGlobalVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT32 Attributes\r
- )\r
-{\r
- UINTN Index;\r
- UINTN NameLength;\r
-\r
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){\r
- //\r
- // Try list 1, exactly match.\r
- //\r
- for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) {\r
- if ((StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) &&\r
- (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList[Index].Attributes)) {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- //\r
- // Try list 2.\r
- //\r
- NameLength = StrLen (VariableName) - 4;\r
- for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) {\r
- if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) &&\r
- (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) &&\r
- IsHexaDecimalDigitCharacter (VariableName[NameLength]) &&\r
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) &&\r
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) &&\r
- IsHexaDecimalDigitCharacter (VariableName[NameLength + 3]) &&\r
- (Attributes == 0 || (Attributes & (~EFI_VARIABLE_APPEND_WRITE)) == mGlobalVariableList2[Index].Attributes)) {\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- DEBUG ((EFI_D_INFO, "[Variable]: set global variable with invalid variable name or attributes - %g:%s:%x\n", VendorGuid, VariableName, Attributes));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
/**\r
Mark a variable that will become read-only after leaving the DXE phase of execution.\r
\r
)\r
{\r
VARIABLE_ENTRY *Entry;\r
+ CHAR16 *Name;\r
\r
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_ACCESS_DENIED;\r
}\r
\r
- Entry = AllocateRuntimePool (sizeof (*Entry) + StrSize (VariableName));\r
+ Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (VariableName));\r
if (Entry == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
- Entry->Name = (CHAR16 *) (Entry + 1);\r
- StrCpy (Entry->Name, VariableName);\r
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
+ StrnCpy (Name, VariableName, StrLen (VariableName));\r
CopyGuid (&Entry->Guid, VendorGuid);\r
InsertTailList (&mLockedVariableList, &Entry->Link);\r
\r
return EFI_SUCCESS;\r
}\r
\r
-/**\r
- This code checks if variable should be treated as read-only variable.\r
-\r
- @param[in] VariableName Name of the Variable.\r
- @param[in] VendorGuid GUID of the Variable.\r
-\r
- @retval TRUE This variable is read-only variable.\r
- @retval FALSE This variable is NOT read-only variable.\r
-\r
-**/\r
-BOOLEAN\r
-IsReadOnlyVariable (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid\r
- )\r
-{\r
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) {\r
- if ((StrCmp (VariableName, EFI_SETUP_MODE_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_SIGNATURE_SUPPORT_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_SECURE_BOOT_MODE_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_VENDOR_KEYS_VARIABLE_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_KEK_DEFAULT_VARIABLE_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_PK_DEFAULT_VARIABLE_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_DB_DEFAULT_VARIABLE_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_DBX_DEFAULT_VARIABLE_NAME) == 0) ||\r
- (StrCmp (VariableName, EFI_DBT_DEFAULT_VARIABLE_NAME) == 0)) {\r
- return TRUE;\r
- }\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
/**\r
\r
This code finds variable in storage blocks (Volatile or Non-Volatile).\r
UINTN PayloadSize;\r
LIST_ENTRY *Link;\r
VARIABLE_ENTRY *Entry;\r
+ CHAR16 *Name;\r
\r
//\r
// Check input parameters.\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if (IsReadOnlyVariable (VariableName, VendorGuid)) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
-\r
if (DataSize != 0 && Data == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
}\r
}\r
\r
- Status = CheckEfiGlobalVariable (VariableName, VendorGuid, Attributes);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
//\r
; Link = GetNextNode (&mLockedVariableList, Link)\r
) {\r
Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);\r
- if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Entry->Name, VariableName) == 0)) {\r
+ Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));\r
+ if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) {\r
Status = EFI_WRITE_PROTECTED;\r
DEBUG ((EFI_D_INFO, "[Variable]: Changing readonly variable after leaving DXE phase - %g:%s\n", VendorGuid, VariableName));\r
goto Done;\r
}\r
}\r
\r
+ Status = InternalVarCheckSetVariableCheck (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize));\r
+ if (EFI_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+\r
//\r
// Check whether the input variable is already existed.\r
//\r
// 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE\r
//\r
Status = EFI_INVALID_PARAMETER;\r
+ DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable with different attributes - %g:%s\n", VendorGuid, VariableName));\r
goto Done;\r
}\r
}\r