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 - 2015, 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
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
TotalNeededSize += VariableEntry->VariableSize;\r
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);\r
}\r
+ VA_END (Args);\r
\r
if (RemainingVariableStorageSize >= TotalNeededSize) {\r
//\r
RemainingVariableStorageSize -= VariableEntry->VariableSize;\r
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);\r
}\r
+ VA_END (Args);\r
\r
return TRUE;\r
}\r
@param Attributes Attribute value of the variable found.\r
@param DataSize Size of Data found. If size is less than the\r
data, this value contains the required size.\r
- @param Data Data pointer.\r
+ @param Data The buffer to return the contents of the variable. May be NULL\r
+ with a zero DataSize in order to determine the size buffer needed.\r
\r
@return EFI_INVALID_PARAMETER Invalid parameter.\r
@return EFI_SUCCESS Find the specified variable.\r
IN EFI_GUID *VendorGuid,\r
OUT UINT32 *Attributes OPTIONAL,\r
IN OUT UINTN *DataSize,\r
- OUT VOID *Data\r
+ OUT VOID *Data OPTIONAL\r
)\r
{\r
EFI_STATUS Status;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ if (VariableName[0] == 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
\r
Status = FindVariable (VariableName, VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);\r
}\r
}\r
\r
+ //\r
+ // Special Handling for MOR Lock variable.\r
+ //\r
+ Status = SetVariableCheckHandlerMor (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize));\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ //\r
+ // EFI_ALREADY_STARTED means the SetVariable() action is handled inside of SetVariableCheckHandlerMor().\r
+ // Variable driver can just return SUCCESS.\r
+ //\r
+ return EFI_SUCCESS;\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
Status = VarCheckLibSetVariableCheck (VariableName, VendorGuid, Attributes, PayloadSize, (VOID *) ((UINTN) Data + DataSize - PayloadSize), mRequestSource);\r
if (EFI_ERROR (Status)) {\r
return Status;\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
}\r
\r
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+ //\r
+ // Initialize MOR Lock variable.\r
+ //\r
+ MorLockInit ();\r
+\r
return Status;\r
}\r
\r