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 - 2019, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2015-2018 Hewlett Packard Enterprise Development LP<BR>\r
+Copyright (c) Microsoft Corporation.<BR>\r
+\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
#include "Variable.h"\r
#include "VariableNonVolatile.h"\r
#include "VariableParsing.h"\r
+#include "VariableRuntimeCache.h"\r
\r
VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;\r
\r
VAR_ERROR_FLAG TempFlag;\r
\r
DEBUG_CODE (\r
- DEBUG ((EFI_D_ERROR, "RecordVarErrorFlag (0x%02x) %s:%g - 0x%08x - 0x%x\n", Flag, VariableName, VendorGuid, Attributes, VariableSize));\r
+ DEBUG ((DEBUG_ERROR, "RecordVarErrorFlag (0x%02x) %s:%g - 0x%08x - 0x%x\n", Flag, VariableName, VendorGuid, Attributes, VariableSize));\r
if (Flag == VAR_ERROR_FLAG_SYSTEM_ERROR) {\r
if (AtRuntime ()) {\r
- DEBUG ((EFI_D_ERROR, "CommonRuntimeVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonRuntimeVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize));\r
+ DEBUG ((DEBUG_ERROR, "CommonRuntimeVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonRuntimeVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize));\r
} else {\r
- DEBUG ((EFI_D_ERROR, "CommonVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize));\r
+ DEBUG ((DEBUG_ERROR, "CommonVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize));\r
}\r
} else {\r
- DEBUG ((EFI_D_ERROR, "CommonMaxUserVariableSpace = 0x%x - CommonUserVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonUserVariableTotalSize));\r
+ DEBUG ((DEBUG_ERROR, "CommonMaxUserVariableSpace = 0x%x - CommonUserVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonUserVariableTotalSize));\r
}\r
);\r
\r
// Update the data in NV cache.\r
//\r
*VarErrFlag = TempFlag;\r
+ Status = SynchronizeRuntimeVariableCache (\r
+ &mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeNvCache,\r
+ 0,\r
+ mNvVariableCache->Size\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
}\r
}\r
}\r
}\r
\r
Flag = mCurrentBootVarErrFlag;\r
- DEBUG ((EFI_D_INFO, "Initialize variable error flag (%02x)\n", Flag));\r
+ DEBUG ((DEBUG_INFO, "Initialize variable error flag (%02x)\n", Flag));\r
\r
Status = FindVariable (\r
VAR_ERROR_FLAG_NAME,\r
VOID *Point1;\r
BOOLEAN FoundAdded;\r
EFI_STATUS Status;\r
+ EFI_STATUS DoneStatus;\r
UINTN CommonVariableTotalSize;\r
UINTN CommonUserVariableTotalSize;\r
UINTN HwErrVariableTotalSize;\r
}\r
\r
Done:\r
+ DoneStatus = EFI_SUCCESS;\r
if (IsVolatile || mVariableModuleGlobal->VariableGlobal.EmuNvMode) {\r
+ DoneStatus = SynchronizeRuntimeVariableCache (\r
+ &mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeVolatileCache,\r
+ 0,\r
+ VariableStoreHeader->Size\r
+ );\r
+ ASSERT_EFI_ERROR (DoneStatus);\r
FreePool (ValidBuffer);\r
} else {\r
//\r
// For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back.\r
//\r
- CopyMem (mNvVariableCache, (UINT8 *)(UINTN)VariableBase, VariableStoreHeader->Size);\r
+ CopyMem (mNvVariableCache, (UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size);\r
+ DoneStatus = SynchronizeRuntimeVariableCache (\r
+ &mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeNvCache,\r
+ 0,\r
+ VariableStoreHeader->Size\r
+ );\r
+ ASSERT_EFI_ERROR (DoneStatus);\r
+ }\r
+\r
+ if (!EFI_ERROR (Status) && EFI_ERROR (DoneStatus)) {\r
+ Status = DoneStatus;\r
}\r
\r
return Status;\r
ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);\r
}\r
\r
- DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));\r
+ DEBUG ((DEBUG_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));\r
}\r
}\r
\r
AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);\r
}\r
\r
- DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));\r
+ DEBUG ((DEBUG_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));\r
}\r
}\r
}\r
VARIABLE_POINTER_TRACK *Variable;\r
VARIABLE_POINTER_TRACK NvVariable;\r
VARIABLE_STORE_HEADER *VariableStoreHeader;\r
+ VARIABLE_RUNTIME_CACHE *VolatileCacheInstance;\r
UINT8 *BufferForMerge;\r
UINTN MergedBufSize;\r
BOOLEAN DataReady;\r
//\r
// Trying to update NV variable prior to the installation of EFI_VARIABLE_WRITE_ARCH_PROTOCOL\r
//\r
- DEBUG ((EFI_D_ERROR, "Update NV variable before EFI_VARIABLE_WRITE_ARCH_PROTOCOL ready - %r\n", EFI_NOT_AVAILABLE_YET));\r
+ DEBUG ((DEBUG_ERROR, "Update NV variable before EFI_VARIABLE_WRITE_ARCH_PROTOCOL ready - %r\n", EFI_NOT_AVAILABLE_YET));\r
return EFI_NOT_AVAILABLE_YET;\r
} else if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) {\r
//\r
// Trying to update volatile authenticated variable prior to the installation of EFI_VARIABLE_WRITE_ARCH_PROTOCOL\r
// The authenticated variable perhaps is not initialized, just return here.\r
//\r
- DEBUG ((EFI_D_ERROR, "Update AUTH variable before EFI_VARIABLE_WRITE_ARCH_PROTOCOL ready - %r\n", EFI_NOT_AVAILABLE_YET));\r
+ DEBUG ((DEBUG_ERROR, "Update AUTH variable before EFI_VARIABLE_WRITE_ARCH_PROTOCOL ready - %r\n", EFI_NOT_AVAILABLE_YET));\r
return EFI_NOT_AVAILABLE_YET;\r
}\r
}\r
}\r
\r
Done:\r
+ if (!EFI_ERROR (Status)) {\r
+ if ((Variable->CurrPtr != NULL && !Variable->Volatile) || (Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {\r
+ VolatileCacheInstance = &(mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeNvCache);\r
+ } else {\r
+ VolatileCacheInstance = &(mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeVolatileCache);\r
+ }\r
+\r
+ if (VolatileCacheInstance->Store != NULL) {\r
+ Status = SynchronizeRuntimeVariableCache (\r
+ VolatileCacheInstance,\r
+ 0,\r
+ VolatileCacheInstance->Store->Size\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+ }\r
+\r
return Status;\r
}\r
\r
}\r
\r
CopyMem (Data, GetVariableDataPtr (Variable.CurrPtr, mVariableModuleGlobal->VariableGlobal.AuthFormat), VarDataSize);\r
- if (Attributes != NULL) {\r
- *Attributes = Variable.CurrPtr->Attributes;\r
- }\r
\r
*DataSize = VarDataSize;\r
UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, TRUE, FALSE, FALSE, FALSE, &gVariableInfo);\r
}\r
\r
Done:\r
+ if (Status == EFI_SUCCESS || Status == EFI_BUFFER_TOO_SMALL) {\r
+ if (Attributes != NULL && Variable.CurrPtr != NULL) {\r
+ *Attributes = Variable.CurrPtr->Attributes;\r
+ }\r
+ }\r
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);\r
return Status;\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(0x%08x) with different attributes(0x%08x) - %g:%s\n", Variable.CurrPtr->Attributes, Attributes, VendorGuid, VariableName));\r
+ DEBUG ((DEBUG_INFO, "[Variable]: Rewritten a preexisting variable(0x%08x) with different attributes(0x%08x) - %g:%s\n", Variable.CurrPtr->Attributes, Attributes, VendorGuid, VariableName));\r
goto Done;\r
}\r
}\r
ErrorFlag = TRUE;\r
}\r
}\r
+ if (mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeHobCache.Store != NULL) {\r
+ Status = SynchronizeRuntimeVariableCache (\r
+ &mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeHobCache,\r
+ 0,\r
+ mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeHobCache.Store->Size\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
if (ErrorFlag) {\r
//\r
// We still have HOB variable(s) not flushed in flash.\r
//\r
// All HOB variables have been flushed in flash.\r
//\r
- DEBUG ((EFI_D_INFO, "Variable driver: all HOB variables have been flushed in flash.\n"));\r
+ DEBUG ((DEBUG_INFO, "Variable driver: all HOB variables have been flushed in flash.\n"));\r
+ if (mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.HobFlushComplete != NULL) {\r
+ *(mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.HobFlushComplete) = TRUE;\r
+ }\r
if (!AtRuntime ()) {\r
FreePool ((VOID *) VariableStoreHeader);\r
}\r
GetVariableHeaderSize (mVariableModuleGlobal->VariableGlobal.AuthFormat);\r
Status = AuthVariableLibInitialize (&mAuthContextIn, &mAuthContextOut);\r
if (!EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "Variable driver will work with auth variable support!\n"));\r
+ DEBUG ((DEBUG_INFO, "Variable driver will work with auth variable support!\n"));\r
mVariableModuleGlobal->VariableGlobal.AuthSupport = TRUE;\r
if (mAuthContextOut.AuthVarEntry != NULL) {\r
for (Index = 0; Index < mAuthContextOut.AuthVarEntryCount; Index++) {\r
}\r
}\r
} else if (Status == EFI_UNSUPPORTED) {\r
- DEBUG ((EFI_D_INFO, "NOTICE - AuthVariableLibInitialize() returns %r!\n", Status));\r
- DEBUG ((EFI_D_INFO, "Variable driver will continue to work without auth variable support!\n"));\r
+ DEBUG ((DEBUG_INFO, "NOTICE - AuthVariableLibInitialize() returns %r!\n", Status));\r
+ DEBUG ((DEBUG_INFO, "Variable driver will continue to work without auth variable support!\n"));\r
mVariableModuleGlobal->VariableGlobal.AuthSupport = FALSE;\r
Status = EFI_SUCCESS;\r
}\r
return EFI_OUT_OF_RESOURCES;\r
}\r
} else {\r
- DEBUG ((EFI_D_ERROR, "HOB Variable Store header is corrupted!\n"));\r
+ DEBUG ((DEBUG_ERROR, "HOB Variable Store header is corrupted!\n"));\r
}\r
}\r
\r
// has been initialized in InitNonVolatileVariableStore().\r
//\r
if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {\r
- DEBUG ((EFI_D_INFO, "Variable driver will work with auth variable format!\n"));\r
+ DEBUG ((DEBUG_INFO, "Variable driver will work with auth variable format!\n"));\r
//\r
// Set AuthSupport to FALSE first, VariableWriteServiceInitialize() will initialize it.\r
//\r
mVariableModuleGlobal->VariableGlobal.AuthSupport = FALSE;\r
VariableGuid = &gEfiAuthenticatedVariableGuid;\r
} else {\r
- DEBUG ((EFI_D_INFO, "Variable driver will work without auth variable support!\n"));\r
+ DEBUG ((DEBUG_INFO, "Variable driver will work without auth variable support!\n"));\r
mVariableModuleGlobal->VariableGlobal.AuthSupport = FALSE;\r
VariableGuid = &gEfiVariableGuid;\r
}\r
\r
return Status;\r
}\r
-\r