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 - 2016, 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
//\r
// Update the data in NV cache.\r
//\r
- *VarErrFlag = Flag;\r
+ *VarErrFlag = TempFlag;\r
}\r
}\r
}\r
mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize;\r
mVariableModuleGlobal->CommonUserVariableTotalSize = CommonUserVariableTotalSize;\r
} else {\r
+ mVariableModuleGlobal->HwErrVariableTotalSize = 0;\r
+ mVariableModuleGlobal->CommonVariableTotalSize = 0;\r
+ mVariableModuleGlobal->CommonUserVariableTotalSize = 0;\r
Variable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase);\r
while (IsValidVariableHeader (Variable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) {\r
NextVariable = GetNextVariablePtr (Variable);\r
// go to delete this variable in variable HOB and\r
// try to flush other variables from HOB to flash.\r
//\r
+ UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, FALSE, TRUE, FALSE);\r
FlushHobVariableToFlash (VariableName, VendorGuid);\r
return EFI_SUCCESS;\r
}\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
UINT32 HwErrStorageSize;\r
UINT32 MaxUserNvVariableSpaceSize;\r
UINT32 BoottimeReservedNvVariableSpaceSize;\r
+ EFI_STATUS Status;\r
+ VOID *FtwProtocol;\r
\r
mVariableModuleGlobal->FvbInstance = NULL;\r
\r
//\r
CopyMem (NvStorageData, (UINT8 *) (UINTN) NvStorageBase, NvStorageSize);\r
\r
+ Status = GetFtwProtocol ((VOID **)&FtwProtocol);\r
//\r
- // Check the FTW last write data hob.\r
+ // If FTW protocol has been installed, no need to check FTW last write data hob.\r
//\r
- GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid);\r
- if (GuidHob != NULL) {\r
- FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) GET_GUID_HOB_DATA (GuidHob);\r
- if (FtwLastWriteData->TargetAddress == NvStorageBase) {\r
- DEBUG ((EFI_D_INFO, "Variable: NV storage is backed up in spare block: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress));\r
- //\r
- // Copy the backed up NV storage data to the memory buffer from spare block.\r
- //\r
- CopyMem (NvStorageData, (UINT8 *) (UINTN) (FtwLastWriteData->SpareAddress), NvStorageSize);\r
- } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) &&\r
- (FtwLastWriteData->TargetAddress < (NvStorageBase + NvStorageSize))) {\r
- //\r
- // Flash NV storage from the Offset is backed up in spare block.\r
- //\r
- BackUpOffset = (UINT32) (FtwLastWriteData->TargetAddress - NvStorageBase);\r
- BackUpSize = NvStorageSize - BackUpOffset;\r
- DEBUG ((EFI_D_INFO, "Variable: High partial NV storage from offset: %x is backed up in spare block: 0x%x\n", BackUpOffset, (UINTN) FtwLastWriteData->SpareAddress));\r
- //\r
- // Copy the partial backed up NV storage data to the memory buffer from spare block.\r
- //\r
- CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) FtwLastWriteData->SpareAddress, BackUpSize);\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // Check the FTW last write data hob.\r
+ //\r
+ GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid);\r
+ if (GuidHob != NULL) {\r
+ FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) GET_GUID_HOB_DATA (GuidHob);\r
+ if (FtwLastWriteData->TargetAddress == NvStorageBase) {\r
+ DEBUG ((EFI_D_INFO, "Variable: NV storage is backed up in spare block: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress));\r
+ //\r
+ // Copy the backed up NV storage data to the memory buffer from spare block.\r
+ //\r
+ CopyMem (NvStorageData, (UINT8 *) (UINTN) (FtwLastWriteData->SpareAddress), NvStorageSize);\r
+ } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) &&\r
+ (FtwLastWriteData->TargetAddress < (NvStorageBase + NvStorageSize))) {\r
+ //\r
+ // Flash NV storage from the Offset is backed up in spare block.\r
+ //\r
+ BackUpOffset = (UINT32) (FtwLastWriteData->TargetAddress - NvStorageBase);\r
+ BackUpSize = NvStorageSize - BackUpOffset;\r
+ DEBUG ((EFI_D_INFO, "Variable: High partial NV storage from offset: %x is backed up in spare block: 0x%x\n", BackUpOffset, (UINTN) FtwLastWriteData->SpareAddress));\r
+ //\r
+ // Copy the partial backed up NV storage data to the memory buffer from spare block.\r
+ //\r
+ CopyMem (NvStorageData + BackUpOffset, (UINT8 *) (UINTN) FtwLastWriteData->SpareAddress, BackUpSize);\r
+ }\r
}\r
}\r
\r
}\r
\r
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
+\r
+ //\r
+ // Initialize MOR Lock variable.\r
+ //\r
+ MorLockInit ();\r
+\r
return Status;\r
}\r
\r