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) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
\r
AUTH_VAR_LIB_CONTEXT_OUT mAuthContextOut;\r
\r
-/**\r
-\r
- SecureBoot Hook for auth variable update.\r
-\r
- @param[in] VariableName Name of Variable to be found.\r
- @param[in] VendorGuid Variable vendor GUID.\r
-**/\r
-VOID\r
-EFIAPI\r
-SecureBootHook (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid\r
- );\r
-\r
-/**\r
- Initialization for MOR Lock Control.\r
-\r
- @retval EFI_SUCEESS MorLock initialization success.\r
- @return Others Some error occurs.\r
-**/\r
-EFI_STATUS\r
-MorLockInit (\r
- VOID\r
- );\r
-\r
-/**\r
- This service is an MOR/MorLock checker handler for the SetVariable().\r
-\r
- @param VariableName the name of the vendor's variable, as a\r
- Null-Terminated Unicode String\r
- @param VendorGuid Unify identifier for vendor.\r
- @param Attributes Point to memory location to return the attributes of variable. If the point\r
- is NULL, the parameter would be ignored.\r
- @param DataSize The size in bytes of Data-Buffer.\r
- @param Data Point to the content of the variable.\r
-\r
- @retval EFI_SUCCESS The MOR/MorLock check pass, and Variable driver can store the variable data.\r
- @retval EFI_INVALID_PARAMETER The MOR/MorLock data or data size or attributes is not allowed for MOR variable.\r
- @retval EFI_ACCESS_DENIED The MOR/MorLock is locked.\r
- @retval EFI_ALREADY_STARTED The MorLock variable is handled inside this function.\r
- Variable driver can just return EFI_SUCCESS.\r
-**/\r
-EFI_STATUS\r
-SetVariableCheckHandlerMor (\r
- IN CHAR16 *VariableName,\r
- IN EFI_GUID *VendorGuid,\r
- IN UINT32 Attributes,\r
- IN UINTN DataSize,\r
- IN VOID *Data\r
- );\r
-\r
/**\r
Routine used to track statistical information about variable usage.\r
The data is stored in the EFI system table so it can be accessed later.\r
// Install the new variable if it is not NULL.\r
//\r
if (NewVariable != NULL) {\r
- if ((UINTN) (CurrPtr - ValidBuffer) + NewVariableSize > VariableStoreHeader->Size) {\r
+ if (((UINTN) CurrPtr - (UINTN) ValidBuffer) + NewVariableSize > VariableStoreHeader->Size) {\r
//\r
// No enough space to store the new variable.\r
//\r
// If volatile variable store, just copy valid buffer.\r
//\r
SetMem ((UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size, 0xff);\r
- CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) (CurrPtr - ValidBuffer));\r
- *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);\r
+ CopyMem ((UINT8 *) (UINTN) VariableBase, ValidBuffer, (UINTN) CurrPtr - (UINTN) ValidBuffer);\r
+ *LastVariableOffset = (UINTN) CurrPtr - (UINTN) ValidBuffer;\r
Status = EFI_SUCCESS;\r
} else {\r
//\r
(VARIABLE_STORE_HEADER *) ValidBuffer\r
);\r
if (!EFI_ERROR (Status)) {\r
- *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer);\r
+ *LastVariableOffset = (UINTN) CurrPtr - (UINTN) ValidBuffer;\r
mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize;\r
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;\r
mVariableModuleGlobal->CommonUserVariableTotalSize = CommonUserVariableTotalSize;\r
//\r
// No enough space for Variable[Index].\r
//\r
+ VA_END (Args);\r
return FALSE;\r
}\r
//\r
@param[in] VendorGuid Variable Vendor Guid.\r
@param[out] VariablePtr Pointer to variable header address.\r
\r
- @return EFI_SUCCESS Find the specified variable.\r
- @return EFI_NOT_FOUND Not found.\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND The next variable was not found.\r
+ @retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while VendorGuid is NULL.\r
+ @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and\r
+ GUID of an existing variable.\r
\r
**/\r
EFI_STATUS\r
\r
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
if (Variable.CurrPtr == NULL || EFI_ERROR (Status)) {\r
+ //\r
+ // For VariableName is an empty string, FindVariable() will try to find and return\r
+ // the first qualified variable, and if FindVariable() returns error (EFI_NOT_FOUND)\r
+ // as no any variable is found, still go to return the error (EFI_NOT_FOUND).\r
+ //\r
+ if (VariableName[0] != 0) {\r
+ //\r
+ // For VariableName is not an empty string, and FindVariable() returns error as\r
+ // VariableName and VendorGuid are not a name and GUID of an existing variable,\r
+ // there is no way to get next variable, follow spec to return EFI_INVALID_PARAMETER.\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ }\r
goto Done;\r
}\r
\r
Caution: This function may receive untrusted input.\r
This function may be invoked in SMM mode. This function will do basic validation, before parse the data.\r
\r
- @param VariableNameSize Size of the variable name.\r
+ @param VariableNameSize The size of the VariableName buffer. The size must be large\r
+ enough to fit input string supplied in VariableName buffer.\r
@param VariableName Pointer to variable name.\r
@param VendorGuid Variable Vendor Guid.\r
\r
- @return EFI_INVALID_PARAMETER Invalid parameter.\r
- @return EFI_SUCCESS Find the specified variable.\r
- @return EFI_NOT_FOUND Not found.\r
- @return EFI_BUFFER_TO_SMALL DataSize is too small for the result.\r
+ @retval EFI_SUCCESS The function completed successfully.\r
+ @retval EFI_NOT_FOUND The next variable was not found.\r
+ @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the result.\r
+ VariableNameSize has been updated with the size needed to complete the request.\r
+ @retval EFI_INVALID_PARAMETER VariableNameSize is NULL.\r
+ @retval EFI_INVALID_PARAMETER VariableName is NULL.\r
+ @retval EFI_INVALID_PARAMETER VendorGuid is NULL.\r
+ @retval EFI_INVALID_PARAMETER The input values of VariableName and VendorGuid are not a name and\r
+ GUID of an existing variable.\r
+ @retval EFI_INVALID_PARAMETER Null-terminator is not found in the first VariableNameSize bytes of\r
+ the input VariableName buffer.\r
\r
**/\r
EFI_STATUS\r
)\r
{\r
EFI_STATUS Status;\r
+ UINTN MaxLen;\r
UINTN VarNameSize;\r
VARIABLE_HEADER *VariablePtr;\r
\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ //\r
+ // Calculate the possible maximum length of name string, including the Null terminator.\r
+ //\r
+ MaxLen = *VariableNameSize / sizeof (CHAR16);\r
+ if ((MaxLen == 0) || (StrnLenS (VariableName, MaxLen) == MaxLen)) {\r
+ //\r
+ // Null-terminator is not found in the first VariableNameSize bytes of the input VariableName buffer,\r
+ // follow spec to return EFI_INVALID_PARAMETER.\r
+ //\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
Status = VariableServiceGetNextVariableInternal (VariableName, VendorGuid, &VariablePtr);\r
\r
//\r
// Check for reserverd bit in variable attribute.\r
+ // EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is deprecated but we still allow\r
+ // the delete operation of common authenticated variable at user physical presence.\r
+ // So leave EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute check to AuthVariableLib\r
//\r
- if ((Attributes & (~EFI_VARIABLE_ATTRIBUTES_MASK)) != 0) {\r
+ if ((Attributes & (~(EFI_VARIABLE_ATTRIBUTES_MASK | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS))) != 0) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
return EFI_VOLUME_CORRUPTED;\r
}\r
\r
- VariableStoreBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) FvHeader + FvHeader->HeaderLength);\r
- VariableStoreLength = (UINT64) (NvStorageSize - FvHeader->HeaderLength);\r
+ VariableStoreBase = (UINTN) FvHeader + FvHeader->HeaderLength;\r
+ VariableStoreLength = NvStorageSize - FvHeader->HeaderLength;\r
\r
mNvFvHeaderCache = FvHeader;\r
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = VariableStoreBase;\r
}\r
\r
if (!EFI_ERROR (Status)) {\r
- for (Index = 0; Index < sizeof (mVariableEntryProperty) / sizeof (mVariableEntryProperty[0]); Index++) {\r
+ for (Index = 0; Index < ARRAY_SIZE (mVariableEntryProperty); Index++) {\r
VariableEntry = &mVariableEntryProperty[Index];\r
Status = VarCheckLibVariablePropertySet (VariableEntry->Name, VariableEntry->Guid, &VariableEntry->VariableProperty);\r
ASSERT_EFI_ERROR (Status);\r
GuidHob = GetFirstGuidHob (VariableGuid);\r
if (GuidHob != NULL) {\r
VariableStoreHeader = GET_GUID_HOB_DATA (GuidHob);\r
- VariableStoreLength = (UINT64) (GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE));\r
+ VariableStoreLength = GuidHob->Header.HobLength - sizeof (EFI_HOB_GUID_TYPE);\r
if (GetVariableStoreStatus (VariableStoreHeader) == EfiValid) {\r
mVariableModuleGlobal->VariableGlobal.HobVariableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) AllocateRuntimeCopyPool ((UINTN) VariableStoreLength, (VOID *) VariableStoreHeader);\r
if (mVariableModuleGlobal->VariableGlobal.HobVariableBase == 0) {\r