summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStar Zeng <star.zeng@intel.com>2014-03-25 06:56:55 +0000
committerlzeng14 <lzeng14@6f19259b-4bc3-4df7-8a09-765794883524>2014-03-25 06:56:55 +0000
commitb2bd493edbc9f31523210848ef39b4eb6a97f4a5 (patch)
treed05b511724fe5c5de4e6b3382bbcf66b2e2728df
parenta8d8d430510db36bc421dd0cb9f9d6d45f5907ac (diff)
downloadedk2-platforms-b2bd493edbc9f31523210848ef39b4eb6a97f4a5.tar.xz
MdeModulePkg/SecurityPkg Variable: Calculate enough space for PlatformLang and Lang variables and use PcdUefiVariableDefaultLangDeprecate to turn off auto update between PlatformLang and Lang variables.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Guo Dong <guo.dong@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15388 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--IntelFrameworkModulePkg/Universal/BdsDxe/Language.c4
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c344
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h37
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf5
-rw-r--r--MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf5
-rw-r--r--MdePkg/MdePkg.dec3
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c337
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h40
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf3
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf3
10 files changed, 659 insertions, 122 deletions
diff --git a/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c b/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
index 2eab617ae5..4c74b018af 100644
--- a/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
+++ b/IntelFrameworkModulePkg/Universal/BdsDxe/Language.c
@@ -462,7 +462,7 @@ InitializeLanguage (
if (LangCodesSettingRequired) {
if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
- // UEFI 2.1 depricated this variable so we support turning it off
+ // UEFI 2.0 depricated this variable so we support turning it off
//
Status = gRT->SetVariable (
L"LangCodes",
@@ -492,7 +492,7 @@ InitializeLanguage (
if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
- // UEFI 2.1 depricated this variable so we support turning it off
+ // UEFI 2.0 depricated this variable so we support turning it off
//
InitializeLangVariable (L"Lang", LangCodes, (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang), TRUE);
}
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
index 5f128e9d61..9825580d3a 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
@@ -1259,6 +1259,121 @@ VariableGetBestLanguage (
}
/**
+ This function is to check if the remaining variable space is enough to set
+ all Variables from argument list successfully. The purpose of the check
+ is to keep the consistency of the Variables to be in variable storage.
+
+ Note: Variables are assumed to be in same storage.
+ The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
+ so follow the argument sequence to check the Variables.
+
+ @param[in] Attributes Variable attributes for Variable entries.
+ @param ... Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
+ A NULL terminates the list.
+
+ @retval TRUE Have enough variable space to set the Variables successfully.
+ @retval FALSE No enough variable space to set the Variables successfully.
+
+**/
+BOOLEAN
+EFIAPI
+CheckRemainingSpaceForConsistency (
+ IN UINT32 Attributes,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ VA_LIST Args;
+ VARIABLE_ENTRY_CONSISTENCY *VariableEntry;
+ UINT64 MaximumVariableStorageSize;
+ UINT64 RemainingVariableStorageSize;
+ UINT64 MaximumVariableSize;
+ UINTN TotalNeededSize;
+ UINTN OriginalVarSize;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
+ VARIABLE_HEADER *NextVariable;
+
+ //
+ // Non-Volatile related.
+ //
+ VariableStoreHeader = mNvVariableCache;
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ &MaximumVariableStorageSize,
+ &RemainingVariableStorageSize,
+ &MaximumVariableSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ TotalNeededSize = 0;
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ TotalNeededSize += VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ if (RemainingVariableStorageSize >= TotalNeededSize) {
+ //
+ // Already have enough space.
+ //
+ return TRUE;
+ } else if (AtRuntime ()) {
+ //
+ // At runtime, no reclaim.
+ // The original variable space of Variables can't be reused.
+ //
+ return FALSE;
+ }
+
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ //
+ // Check if Variable[Index] has been present and get its size.
+ //
+ OriginalVarSize = 0;
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ VariableEntry->Name,
+ VariableEntry->Guid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get size of Variable[Index].
+ //
+ NextVariable = GetNextVariablePtr (VariablePtrTrack.CurrPtr);
+ OriginalVarSize = (UINTN) NextVariable - (UINTN) VariablePtrTrack.CurrPtr;
+ //
+ // Add the original size of Variable[Index] to remaining variable storage size.
+ //
+ RemainingVariableStorageSize += OriginalVarSize;
+ }
+ if (VariableEntry->VariableSize > RemainingVariableStorageSize) {
+ //
+ // No enough space for Variable[Index].
+ //
+ VA_END (Args);
+ return FALSE;
+ }
+ //
+ // Sub the (new) size of Variable[Index] from remaining variable storage size.
+ //
+ RemainingVariableStorageSize -= VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ return TRUE;
+}
+
+/**
Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
When setting Lang/LangCodes, simultaneously update PlatformLang/PlatformLangCodes.
@@ -1292,6 +1407,9 @@ AutoUpdateLangVariable (
UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes;
+ UINTN VarNameSize;
+ UINTN VarDataSize;
+ VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
//
// Don't do updates for delete operation
@@ -1414,14 +1532,39 @@ AutoUpdateLangVariable (
BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);
//
- // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ // Calculate the needed variable size for Lang variable.
+ //
+ VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+ VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
//
- FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+ // Calculate the needed variable size for PlatformLang variable.
+ //
+ VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+ VarDataSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both Lang and PlatformLang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ //
+ FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
- ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);
+ Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
+ ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable);
+ }
- DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a: Status: %r\n", BestPlatformLang, BestLang, Status));
+ DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));
}
}
@@ -1446,19 +1589,51 @@ AutoUpdateLangVariable (
BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
//
- // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ // Calculate the needed variable size for PlatformLang variable.
+ //
+ VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+ VarDataSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+ //
+ // Calculate the needed variable size for Lang variable.
//
- FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+ VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+ VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both PlatformLang and Lang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ //
+ FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
- AsciiStrSize (BestPlatformLang), Attributes, &Variable);
+ Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
+ AsciiStrSize (BestPlatformLang), Attributes, &Variable);
+ }
DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));
}
}
}
- return Status;
+ if (SetLanguageCodes) {
+ //
+ // Continue to set PlatformLangCodes or LangCodes.
+ //
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
}
/**
@@ -2492,15 +2667,17 @@ VariableServiceSetVariable (
}
}
- //
- // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
- //
- Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
- if (EFI_ERROR (Status)) {
+ if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
- // The auto update operation failed, directly return to avoid inconsistency between PlatformLang and Lang.
+ // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
//
- goto Done;
+ Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
+ if (EFI_ERROR (Status)) {
+ //
+ // The auto update operation failed, directly return to avoid inconsistency between PlatformLang and Lang.
+ //
+ goto Done;
+ }
}
Status = UpdateVariable (VariableName, VendorGuid, Data, DataSize, Attributes, &Variable);
@@ -2525,14 +2702,12 @@ Done:
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
- @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
- @return EFI_UNSUPPORTED The attribute is not supported on this platform.
**/
EFI_STATUS
EFIAPI
-VariableServiceQueryVariableInfo (
+VariableServiceQueryVariableInfoInternal (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
@@ -2545,43 +2720,12 @@ VariableServiceQueryVariableInfo (
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT64 CommonVariableTotalSize;
UINT64 HwErrVariableTotalSize;
+ EFI_STATUS Status;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
CommonVariableTotalSize = 0;
HwErrVariableTotalSize = 0;
- if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
- //
- // Make sure the Attributes combination is supported by the platform.
- //
- return EFI_UNSUPPORTED;
- } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
- //
- // Make sure if runtime bit is set, boot service bit is set also.
- //
- return EFI_INVALID_PARAMETER;
- } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
- //
- // Make sure RT Attribute is set if we are in Runtime phase.
- //
- return EFI_INVALID_PARAMETER;
- } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
- //
- // Make sure Hw Attribute is set with NV.
- //
- return EFI_INVALID_PARAMETER;
- } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
- //
- // Not support authentiated variable write yet.
- //
- return EFI_UNSUPPORTED;
- }
-
- AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
-
if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
//
// Query is Volatile related.
@@ -2653,6 +2797,27 @@ VariableServiceQueryVariableInfo (
} else {
CommonVariableTotalSize += VariableSize;
}
+ } else if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ //
+ // If it is a IN_DELETED_TRANSITION variable,
+ // and there is not also a same ADDED one at the same time,
+ // this IN_DELETED_TRANSITION variable is valid.
+ //
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ GetVariableNamePtr (Variable),
+ &Variable->VendorGuid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State != VAR_ADDED) {
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += VariableSize;
+ } else {
+ CommonVariableTotalSize += VariableSize;
+ }
+ }
}
}
@@ -2674,10 +2839,81 @@ VariableServiceQueryVariableInfo (
*MaximumVariableSize = *RemainingVariableStorageSize - sizeof (VARIABLE_HEADER);
}
- ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
return EFI_SUCCESS;
}
+/**
+
+ This code returns information about the EFI variables.
+
+ @param Attributes Attributes bitmask to specify the type of variables
+ on which to return information.
+ @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
+ @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
+ @return EFI_SUCCESS Query successfully.
+ @return EFI_UNSUPPORTED The attribute is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfo (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ )
+{
+ EFI_STATUS Status;
+
+ if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
+ //
+ // Make sure the Attributes combination is supported by the platform.
+ //
+ return EFI_UNSUPPORTED;
+ } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
+ //
+ // Make sure if runtime bit is set, boot service bit is set also.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
+ //
+ // Make sure RT Attribute is set if we are in Runtime phase.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ //
+ // Make sure Hw Attribute is set with NV.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if ((Attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_APPEND_WRITE)) != 0) {
+ //
+ // Not support authenticated or append variable write yet.
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ MaximumVariableStorageSize,
+ RemainingVariableStorageSize,
+ MaximumVariableSize
+ );
+
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+ return Status;
+}
/**
This function reclaims variable storage if free size is below the threshold.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
index 9c8626cdc4..fa78e4414b 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h
@@ -3,7 +3,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by Variable modules.
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -101,10 +101,12 @@ typedef struct {
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
- UINT32 Attributes;
- UINTN DataSize;
- VOID *Data;
-} VARIABLE_CACHE_ENTRY;
+// UINT32 Attributes;
+ //
+ // Variable size include variable header, name and data.
+ //
+ UINTN VariableSize;
+} VARIABLE_ENTRY_CONSISTENCY;
typedef struct {
EFI_GUID Guid;
@@ -456,6 +458,31 @@ VariableServiceSetVariable (
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
+ @return EFI_SUCCESS Query successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfoInternal (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ );
+
+/**
+
+ This code returns information about the EFI variables.
+
+ @param Attributes Attributes bitmask to specify the type of variables
+ on which to return information.
+ @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
@return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
@return EFI_UNSUPPORTED The attribute is not supported on this platform.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
index c712ba0200..297a6da5a5 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
@@ -2,7 +2,7 @@
# Component description file for Variable module.
#
# This module installs three EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName.
-# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -80,7 +80,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
TRUE
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
index 36436b6db8..1448240d1b 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf
@@ -14,7 +14,7 @@
# This external input must be validated carefully to avoid security issue like
# buffer overflow, integer overflow.
#
-# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -89,7 +89,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
TRUE
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index affff516ef..4daf3e6a75 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1375,7 +1375,8 @@
## If TRUE, the driver diagnostics2 protocol will not be installed.
gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|FALSE|BOOLEAN|0x00000011
- ## Indicates whether EFI 1.1 ISO 639-2 language supports are obsolete
+ ## Indicates whether EFI 1.1 ISO 639-2 language supports are obsolete.
+ # If TRUE, Variable driver will be also not to auto update between PlatformLang and Lang variables.
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate|FALSE|BOOLEAN|0x00000012
## If TRUE, UGA Draw Protocol is still consumed.
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
index 71cd460e0c..8f4a0a8f1b 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
@@ -1509,6 +1509,121 @@ VariableGetBestLanguage (
}
/**
+ This function is to check if the remaining variable space is enough to set
+ all Variables from argument list successfully. The purpose of the check
+ is to keep the consistency of the Variables to be in variable storage.
+
+ Note: Variables are assumed to be in same storage.
+ The set sequence of Variables will be same with the sequence of VariableEntry from argument list,
+ so follow the argument sequence to check the Variables.
+
+ @param[in] Attributes Variable attributes for Variable entries.
+ @param ... Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
+ A NULL terminates the list.
+
+ @retval TRUE Have enough variable space to set the Variables successfully.
+ @retval FALSE No enough variable space to set the Variables successfully.
+
+**/
+BOOLEAN
+EFIAPI
+CheckRemainingSpaceForConsistency (
+ IN UINT32 Attributes,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ VA_LIST Args;
+ VARIABLE_ENTRY_CONSISTENCY *VariableEntry;
+ UINT64 MaximumVariableStorageSize;
+ UINT64 RemainingVariableStorageSize;
+ UINT64 MaximumVariableSize;
+ UINTN TotalNeededSize;
+ UINTN OriginalVarSize;
+ VARIABLE_STORE_HEADER *VariableStoreHeader;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
+ VARIABLE_HEADER *NextVariable;
+
+ //
+ // Non-Volatile related.
+ //
+ VariableStoreHeader = mNvVariableCache;
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ &MaximumVariableStorageSize,
+ &RemainingVariableStorageSize,
+ &MaximumVariableSize
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ TotalNeededSize = 0;
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ TotalNeededSize += VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ if (RemainingVariableStorageSize >= TotalNeededSize) {
+ //
+ // Already have enough space.
+ //
+ return TRUE;
+ } else if (AtRuntime ()) {
+ //
+ // At runtime, no reclaim.
+ // The original variable space of Variables can't be reused.
+ //
+ return FALSE;
+ }
+
+ VA_START (Args, Attributes);
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ while (VariableEntry != NULL) {
+ //
+ // Check if Variable[Index] has been present and get its size.
+ //
+ OriginalVarSize = 0;
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ VariableEntry->Name,
+ VariableEntry->Guid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Get size of Variable[Index].
+ //
+ NextVariable = GetNextVariablePtr (VariablePtrTrack.CurrPtr);
+ OriginalVarSize = (UINTN) NextVariable - (UINTN) VariablePtrTrack.CurrPtr;
+ //
+ // Add the original size of Variable[Index] to remaining variable storage size.
+ //
+ RemainingVariableStorageSize += OriginalVarSize;
+ }
+ if (VariableEntry->VariableSize > RemainingVariableStorageSize) {
+ //
+ // No enough space for Variable[Index].
+ //
+ VA_END (Args);
+ return FALSE;
+ }
+ //
+ // Sub the (new) size of Variable[Index] from remaining variable storage size.
+ //
+ RemainingVariableStorageSize -= VariableEntry->VariableSize;
+ VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
+ }
+ VA_END (Args);
+
+ return TRUE;
+}
+
+/**
Hook the operations in PlatformLangCodes, LangCodes, PlatformLang and Lang.
When setting Lang/LangCodes, simultaneously update PlatformLang/PlatformLangCodes.
@@ -1542,6 +1657,9 @@ AutoUpdateLangVariable (
UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes;
+ UINTN VarNameSize;
+ UINTN VarDataSize;
+ VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
//
// Don't do updates for delete operation
@@ -1664,12 +1782,37 @@ AutoUpdateLangVariable (
BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);
//
- // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ // Calculate the needed variable size for Lang variable.
+ //
+ VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+ VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
//
- FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+ // Calculate the needed variable size for PlatformLang variable.
+ //
+ VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+ VarDataSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both Lang and PlatformLang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously.
+ //
+ FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
- ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);
+ Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang,
+ ISO_639_2_ENTRY_SIZE + 1, Attributes, 0, 0, &Variable, NULL);
+ }
DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a Status: %r\n", BestPlatformLang, BestLang, Status));
}
@@ -1696,19 +1839,51 @@ AutoUpdateLangVariable (
BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
//
- // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ // Calculate the needed variable size for PlatformLang variable.
//
- FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
+ VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
+ VarDataSize = AsciiStrSize (BestPlatformLang);
+ VariableEntry[0].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[0].VariableSize = HEADER_ALIGN (VariableEntry[0].VariableSize);
+ VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
+ //
+ // Calculate the needed variable size for Lang variable.
+ //
+ VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
+ VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
+ VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
+ VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
+ VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
+ VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
+ if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
+ //
+ // No enough variable space to set both PlatformLang and Lang successfully.
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously.
+ //
+ FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
- Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
- AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);
+ Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang,
+ AsciiStrSize (BestPlatformLang), Attributes, 0, 0, &Variable, NULL);
+ }
DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a Status: %r\n", BestLang, BestPlatformLang, Status));
}
}
}
- return Status;
+ if (SetLanguageCodes) {
+ //
+ // Continue to set PlatformLangCodes or LangCodes.
+ //
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
}
/**
@@ -2992,16 +3167,18 @@ VariableServiceSetVariable (
goto Done;
}
}
-
- //
- // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
- //
- Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
- if (EFI_ERROR (Status)) {
+
+ if (!FeaturePcdGet (PcdUefiVariableDefaultLangDeprecate)) {
//
- // The auto update operation failed, directly return to avoid inconsistency between PlatformLang and Lang.
+ // Hook the operation of setting PlatformLangCodes/PlatformLang and LangCodes/Lang.
//
- goto Done;
+ Status = AutoUpdateLangVariable (VariableName, Data, DataSize);
+ if (EFI_ERROR (Status)) {
+ //
+ // The auto update operation failed, directly return to avoid inconsistency between PlatformLang and Lang.
+ //
+ goto Done;
+ }
}
//
@@ -3053,14 +3230,12 @@ Done:
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
- @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
- @return EFI_UNSUPPORTED The attribute is not supported on this platform.
**/
EFI_STATUS
EFIAPI
-VariableServiceQueryVariableInfo (
+VariableServiceQueryVariableInfoInternal (
IN UINT32 Attributes,
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
@@ -3073,38 +3248,12 @@ VariableServiceQueryVariableInfo (
VARIABLE_STORE_HEADER *VariableStoreHeader;
UINT64 CommonVariableTotalSize;
UINT64 HwErrVariableTotalSize;
+ EFI_STATUS Status;
+ VARIABLE_POINTER_TRACK VariablePtrTrack;
CommonVariableTotalSize = 0;
HwErrVariableTotalSize = 0;
- if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
- //
- // Make sure the Attributes combination is supported by the platform.
- //
- return EFI_UNSUPPORTED;
- } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
- //
- // Make sure if runtime bit is set, boot service bit is set also.
- //
- return EFI_INVALID_PARAMETER;
- } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
- //
- // Make sure RT Attribute is set if we are in Runtime phase.
- //
- return EFI_INVALID_PARAMETER;
- } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
- //
- // Make sure Hw Attribute is set with NV.
- //
- return EFI_INVALID_PARAMETER;
- }
-
- AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
-
if((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
//
// Query is Volatile related.
@@ -3176,6 +3325,27 @@ VariableServiceQueryVariableInfo (
} else {
CommonVariableTotalSize += VariableSize;
}
+ } else if (Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) {
+ //
+ // If it is a IN_DELETED_TRANSITION variable,
+ // and there is not also a same ADDED one at the same time,
+ // this IN_DELETED_TRANSITION variable is valid.
+ //
+ VariablePtrTrack.StartPtr = GetStartPointer (VariableStoreHeader);
+ VariablePtrTrack.EndPtr = GetEndPointer (VariableStoreHeader);
+ Status = FindVariableEx (
+ GetVariableNamePtr (Variable),
+ &Variable->VendorGuid,
+ FALSE,
+ &VariablePtrTrack
+ );
+ if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State != VAR_ADDED) {
+ if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ HwErrVariableTotalSize += VariableSize;
+ } else {
+ CommonVariableTotalSize += VariableSize;
+ }
+ }
}
}
@@ -3197,10 +3367,79 @@ VariableServiceQueryVariableInfo (
*MaximumVariableSize = *RemainingVariableStorageSize - sizeof (VARIABLE_HEADER);
}
- ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
return EFI_SUCCESS;
}
+/**
+
+ This code returns information about the EFI variables.
+
+ Caution: This function may receive untrusted input.
+ This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
+
+ @param Attributes Attributes bitmask to specify the type of variables
+ on which to return information.
+ @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
+ @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
+ @return EFI_SUCCESS Query successfully.
+ @return EFI_UNSUPPORTED The attribute is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfo (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ )
+{
+ EFI_STATUS Status;
+
+ if(MaximumVariableStorageSize == NULL || RemainingVariableStorageSize == NULL || MaximumVariableSize == NULL || Attributes == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) {
+ //
+ // Make sure the Attributes combination is supported by the platform.
+ //
+ return EFI_UNSUPPORTED;
+ } else if ((Attributes & (EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS)) == EFI_VARIABLE_RUNTIME_ACCESS) {
+ //
+ // Make sure if runtime bit is set, boot service bit is set also.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if (AtRuntime () && ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0)) {
+ //
+ // Make sure RT Attribute is set if we are in Runtime phase.
+ //
+ return EFI_INVALID_PARAMETER;
+ } else if ((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) {
+ //
+ // Make sure Hw Attribute is set with NV.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Status = VariableServiceQueryVariableInfoInternal (
+ Attributes,
+ MaximumVariableStorageSize,
+ RemainingVariableStorageSize,
+ MaximumVariableSize
+ );
+
+ ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+ return Status;
+}
/**
This function reclaims variable storage if free size is below the threshold.
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
index b4512d2cca..b9f4f43402 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
@@ -2,7 +2,7 @@
The internal header file includes the common header files, defines
internal structure and functions used by Variable modules.
-Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -111,10 +111,12 @@ typedef struct {
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
- UINT32 Attributes;
- UINTN DataSize;
- VOID *Data;
-} VARIABLE_CACHE_ENTRY;
+// UINT32 Attributes;
+ //
+ // Variable size include variable header, name and data.
+ //
+ UINTN VariableSize;
+} VARIABLE_ENTRY_CONSISTENCY;
typedef struct {
EFI_GUID Guid;
@@ -580,6 +582,34 @@ VariableServiceSetVariable (
@param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
associated with the attributes specified.
+ @return EFI_SUCCESS Query successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+VariableServiceQueryVariableInfoInternal (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+ );
+
+/**
+
+ This code returns information about the EFI variables.
+
+ Caution: This function may receive untrusted input.
+ This function may be invoked in SMM mode. This function will do basic validation, before parse the data.
+
+ @param Attributes Attributes bitmask to specify the type of variables
+ on which to return information.
+ @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available
+ for the EFI variables associated with the attributes specified.
+ @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available
+ for EFI variables associated with the attributes specified.
+ @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables
+ associated with the attributes specified.
+
@return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied.
@return EFI_SUCCESS Query successfully.
@return EFI_UNSUPPORTED The attribute is not supported on this platform.
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
index a05c048494..41e85c0156 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
@@ -99,7 +99,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
TRUE
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
index e7c6de8b94..0e3fc514b4 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
@@ -102,7 +102,8 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize
[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## SOMETIME_CONSUMES (statistic the information of variable.)
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
+ gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
[Depex]
TRUE