mirror of https://github.com/acidanthera/audk.git
MdeModulePkg Variable: Handle variable Attributes mismatch case
between variable HOB and NV storage. Variable HOB may be built by a system that supports and loads variable default, the variables in the HOB will be flush to NV storage after variable write search ready. After that, if the variable's Attributes is changed by someone and system reboots and tries to load default again, the variable Attributes mismatch case between variable HOB and NV storage will appear. Original code did not handle the case correctly, that may eventually cause NV storage contains two valid same variables that will lead to system hang if GetNextVariableName() called. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18225 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
c533ed3ebb
commit
313491310c
|
@ -2178,6 +2178,34 @@ UpdateVariable (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check if CacheVariable points to the variable in variable HOB.
|
||||||
|
// If yes, let CacheVariable points to the variable in NV variable cache.
|
||||||
|
//
|
||||||
|
if ((CacheVariable->CurrPtr != NULL) &&
|
||||||
|
(mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) &&
|
||||||
|
(CacheVariable->StartPtr == GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.HobVariableBase))
|
||||||
|
) {
|
||||||
|
CacheVariable->StartPtr = GetStartPointer (mNvVariableCache);
|
||||||
|
CacheVariable->EndPtr = GetEndPointer (mNvVariableCache);
|
||||||
|
CacheVariable->Volatile = FALSE;
|
||||||
|
Status = FindVariableEx (VariableName, VendorGuid, FALSE, CacheVariable);
|
||||||
|
if (CacheVariable->CurrPtr == NULL || EFI_ERROR (Status)) {
|
||||||
|
//
|
||||||
|
// There is no matched variable in NV variable cache.
|
||||||
|
//
|
||||||
|
if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
|
||||||
|
//
|
||||||
|
// It is to delete variable,
|
||||||
|
// go to delete this variable in variable HOB and
|
||||||
|
// try to flush other variables from HOB to flash.
|
||||||
|
//
|
||||||
|
FlushHobVariableToFlash (VariableName, VendorGuid);
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((CacheVariable->CurrPtr == NULL) || CacheVariable->Volatile) {
|
if ((CacheVariable->CurrPtr == NULL) || CacheVariable->Volatile) {
|
||||||
Variable = CacheVariable;
|
Variable = CacheVariable;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3895,6 +3923,7 @@ FlushHobVariableToFlash (
|
||||||
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
||||||
VARIABLE_HEADER *Variable;
|
VARIABLE_HEADER *Variable;
|
||||||
VOID *VariableData;
|
VOID *VariableData;
|
||||||
|
VARIABLE_POINTER_TRACK VariablePtrTrack;
|
||||||
BOOLEAN ErrorFlag;
|
BOOLEAN ErrorFlag;
|
||||||
|
|
||||||
ErrorFlag = FALSE;
|
ErrorFlag = FALSE;
|
||||||
|
@ -3923,17 +3952,22 @@ FlushHobVariableToFlash (
|
||||||
!CompareGuid (VendorGuid, GetVendorGuidPtr (Variable)) ||
|
!CompareGuid (VendorGuid, GetVendorGuidPtr (Variable)) ||
|
||||||
StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) {
|
StrCmp (VariableName, GetVariableNamePtr (Variable)) != 0) {
|
||||||
VariableData = GetVariableDataPtr (Variable);
|
VariableData = GetVariableDataPtr (Variable);
|
||||||
Status = VariableServiceSetVariable (
|
FindVariable (GetVariableNamePtr (Variable), GetVendorGuidPtr (Variable), &VariablePtrTrack, &mVariableModuleGlobal->VariableGlobal, FALSE);
|
||||||
|
Status = UpdateVariable (
|
||||||
GetVariableNamePtr (Variable),
|
GetVariableNamePtr (Variable),
|
||||||
GetVendorGuidPtr (Variable),
|
GetVendorGuidPtr (Variable),
|
||||||
Variable->Attributes,
|
VariableData,
|
||||||
DataSizeOfVariable (Variable),
|
DataSizeOfVariable (Variable),
|
||||||
VariableData
|
Variable->Attributes,
|
||||||
);
|
0,
|
||||||
|
0,
|
||||||
|
&VariablePtrTrack,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", GetVendorGuidPtr (Variable), GetVariableNamePtr (Variable), Status));
|
DEBUG ((EFI_D_INFO, "Variable driver flush the HOB variable to flash: %g %s %r\n", GetVendorGuidPtr (Variable), GetVariableNamePtr (Variable), Status));
|
||||||
} else {
|
} else {
|
||||||
//
|
//
|
||||||
// The updated or deleted variable is matched with the HOB variable.
|
// The updated or deleted variable is matched with this HOB variable.
|
||||||
// Don't break here because we will try to set other HOB variables
|
// Don't break here because we will try to set other HOB variables
|
||||||
// since this variable could be set successfully.
|
// since this variable could be set successfully.
|
||||||
//
|
//
|
||||||
|
@ -3988,6 +4022,8 @@ VariableWriteServiceInitialize (
|
||||||
EFI_PHYSICAL_ADDRESS NvStorageBase;
|
EFI_PHYSICAL_ADDRESS NvStorageBase;
|
||||||
VARIABLE_ENTRY_PROPERTY *VariableEntry;
|
VARIABLE_ENTRY_PROPERTY *VariableEntry;
|
||||||
|
|
||||||
|
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||||
|
|
||||||
NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
|
NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64);
|
||||||
if (NvStorageBase == 0) {
|
if (NvStorageBase == 0) {
|
||||||
NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);
|
NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase);
|
||||||
|
@ -4018,6 +4054,7 @@ VariableWriteServiceInitialize (
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
|
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -4065,6 +4102,7 @@ VariableWriteServiceInitialize (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue