From 952ba83c4781c7e7fff74fc32fd840a86731d8f6 Mon Sep 17 00:00:00 2001 From: Star Zeng Date: Tue, 27 Jan 2015 08:44:10 +0000 Subject: [PATCH] SecurityPkg Variable: Implement variable quota management. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng Reviewed-by: Jiewen Yao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16670 6f19259b-4bc3-4df7-8a09-765794883524 --- .../RuntimeDxe/VarCheck.c | 250 ++++++------ .../RuntimeDxe/Variable.c | 377 ++++++++++++++++-- .../RuntimeDxe/Variable.h | 36 +- .../RuntimeDxe/VariableDxe.c | 8 + .../RuntimeDxe/VariableRuntimeDxe.inf | 3 + .../RuntimeDxe/VariableSmm.c | 8 + .../RuntimeDxe/VariableSmm.inf | 7 +- 7 files changed, 528 insertions(+), 161 deletions(-) diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c index 76bd7b4d90..3f4beb07f0 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VarCheck.c @@ -48,14 +48,6 @@ typedef struct { INTERNAL_VAR_CHECK_FUNCTION CheckFunction; } UEFI_DEFINED_VARIABLE_ENTRY; -typedef struct _EFI_LOAD_OPTION { - UINT32 Attributes; - UINT16 FilePathListLength; -//CHAR16 Description[]; -//EFI_DEVICE_PATH_PROTOCOL FilePathList[]; -//UINT8 OptionalData[]; -} EFI_LOAD_OPTION; - /** Internal check for load option. @@ -75,16 +67,16 @@ InternalVarCheckLoadOption ( IN VOID *Data ) { - EFI_LOAD_OPTION *LoadOption; + UINT16 FilePathListLength; CHAR16 *Description; EFI_DEVICE_PATH_PROTOCOL *FilePathList; - LoadOption = (EFI_LOAD_OPTION *) Data; + FilePathListLength = *((UINT16 *) ((UINTN) Data + sizeof (UINT32))); // // Check Description // - Description = (CHAR16 *) ((UINTN) Data + sizeof (EFI_LOAD_OPTION)); + Description = (CHAR16 *) ((UINTN) Data + sizeof (UINT32) + sizeof (UINT16)); while (Description < (CHAR16 *) ((UINTN) Data + DataSize)) { if (*Description == L'\0') { break; @@ -100,16 +92,16 @@ InternalVarCheckLoadOption ( // Check FilePathList // FilePathList = (EFI_DEVICE_PATH_PROTOCOL *) Description; - if ((UINTN) FilePathList > (MAX_ADDRESS - LoadOption->FilePathListLength)) { + if ((UINTN) FilePathList > (MAX_ADDRESS - FilePathListLength)) { return EFI_INVALID_PARAMETER; } - if (((UINTN) FilePathList + LoadOption->FilePathListLength) > ((UINTN) Data + DataSize)) { + if (((UINTN) FilePathList + FilePathListLength) > ((UINTN) Data + DataSize)) { return EFI_INVALID_PARAMETER; } - if (LoadOption->FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { + if (FilePathListLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) { return EFI_INVALID_PARAMETER; } - if (!IsDevicePathValid (FilePathList, LoadOption->FilePathListLength)) { + if (!IsDevicePathValid (FilePathList, FilePathListLength)) { return EFI_INVALID_PARAMETER; } @@ -573,7 +565,7 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = { VAR_CHECK_VARIABLE_PROPERTY_REVISION, 0, VARIABLE_ATTRIBUTE_NV_BS_RT, - sizeof (EFI_LOAD_OPTION), + sizeof (UINT32) + sizeof (UINT16), MAX_UINTN }, InternalVarCheckLoadOption @@ -584,7 +576,7 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = { VAR_CHECK_VARIABLE_PROPERTY_REVISION, 0, VARIABLE_ATTRIBUTE_NV_BS_RT, - sizeof (EFI_LOAD_OPTION), + sizeof (UINT32) + sizeof (UINT16), MAX_UINTN }, InternalVarCheckLoadOption @@ -658,8 +650,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { VARIABLE_ATTRIBUTE_NV_BS, sizeof (UINT8), sizeof (UINT8) - }, - NULL + } }, { &gEfiCustomModeEnableGuid, @@ -670,8 +661,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { VARIABLE_ATTRIBUTE_NV_BS, sizeof (UINT8), sizeof (UINT8) - }, - NULL + } }, { &gEfiVendorKeysNvGuid, @@ -682,8 +672,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { VARIABLE_ATTRIBUTE_NV_BS_RT_AT, sizeof (UINT8), sizeof (UINT8) - }, - NULL + } }, { &gEfiAuthenticatedVariableGuid, @@ -694,8 +683,7 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { VARIABLE_ATTRIBUTE_NV_BS_RT_AW, sizeof (UINT8), MAX_UINTN - }, - NULL + } }, { &gEfiCertDbGuid, @@ -706,8 +694,18 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = { VARIABLE_ATTRIBUTE_NV_BS_RT_AT, sizeof (UINT32), MAX_UINTN - }, - NULL + } + }, + { + &gEdkiiVarErrorFlagGuid, + VAR_ERROR_FLAG_NAME, + { + VAR_CHECK_VARIABLE_PROPERTY_REVISION, + VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY, + VARIABLE_ATTRIBUTE_NV_BS_RT, + sizeof (VAR_ERROR_FLAG), + sizeof (VAR_ERROR_FLAG) + } }, }; @@ -738,7 +736,7 @@ GetUefiDefinedVariableProperty ( UINTN Index; UINTN NameLength; - if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){ + if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)) { // // Try list 1, exactly match. // @@ -770,14 +768,13 @@ GetUefiDefinedVariableProperty ( *VariableProperty = &mGlobalVariableList2[Index].VariableProperty; return EFI_SUCCESS; } - } else { - if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) { - if (VarCheckFunction != NULL) { - *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction; - } - *VariableProperty = &mGlobalVariableList2[Index].VariableProperty; - return EFI_SUCCESS; + } + if (StrCmp (mGlobalVariableList2[Index].Name, VariableName) == 0) { + if (VarCheckFunction != NULL) { + *VarCheckFunction = mGlobalVariableList2[Index].CheckFunction; } + *VariableProperty = &mGlobalVariableList2[Index].VariableProperty; + return EFI_SUCCESS; } } @@ -812,7 +809,6 @@ GetUefiDefinedVariableProperty ( @param[in] VariableName Pointer to variable name. @param[in] VendorGuid Variable Vendor Guid. - @param[out] VarCheckFunction Pointer to check function. @return Pointer to variable property. @@ -820,17 +816,13 @@ GetUefiDefinedVariableProperty ( VAR_CHECK_VARIABLE_PROPERTY * GetVariableDriverVariableProperty ( IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - OUT INTERNAL_VAR_CHECK_FUNCTION *VarCheckFunction OPTIONAL + IN EFI_GUID *VendorGuid ) { UINTN Index; for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) { if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) { - if (VarCheckFunction != NULL) { - *VarCheckFunction = mVariableDriverVariableList[Index].CheckFunction; - } return &mVariableDriverVariableList[Index].VariableProperty; } } @@ -881,26 +873,27 @@ InternalVarCheckSetVariableCheck ( } Property = NULL; - Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName)); - return Status; + VarCheckFunction = NULL; + + for ( Link = GetFirstNode (&mVarCheckVariableList) + ; !IsNull (&mVarCheckVariableList, Link) + ; Link = GetNextNode (&mVarCheckVariableList, Link) + ) { + Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link); + Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry)); + if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) { + Property = &Entry->VariableProperty; + break; + } } if (Property == NULL) { - Property = GetVariableDriverVariableProperty (VariableName, VendorGuid, &VarCheckFunction); + Property = GetVariableDriverVariableProperty (VariableName, VendorGuid); } if (Property == NULL) { - VarCheckFunction = NULL; - for ( Link = GetFirstNode (&mVarCheckVariableList) - ; !IsNull (&mVarCheckVariableList, Link) - ; Link = GetNextNode (&mVarCheckVariableList, Link) - ) { - Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link); - Name = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry)); - if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Name, VariableName) == 0)) { - Property = &Entry->VariableProperty; - break; - } + Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName)); + return Status; } } if (Property != NULL) { @@ -908,30 +901,29 @@ InternalVarCheckSetVariableCheck ( DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName)); return EFI_WRITE_PROTECTED; } - if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) { + if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) { // - // Do not check delete variable. + // Not to delete variable. // - return EFI_SUCCESS; - } - if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) { - DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName)); - return EFI_INVALID_PARAMETER; - } - if (DataSize != 0) { - if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) { - DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail %r - %g:%s\n", EFI_INVALID_PARAMETER, VendorGuid, VariableName)); + if ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes) { + DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName)); return EFI_INVALID_PARAMETER; } - if (VarCheckFunction != NULL) { - Status = VarCheckFunction ( - Property, - DataSize, - Data - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName)); - return Status; + if (DataSize != 0) { + if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) { + DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName)); + return EFI_INVALID_PARAMETER; + } + if (VarCheckFunction != NULL) { + Status = VarCheckFunction ( + Property, + DataSize, + Data + ); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName)); + return Status; + } } } } @@ -1047,18 +1039,20 @@ VarCheckRegisterSetVariableCheckHandler ( } /** - Internal variable property get. + Variable property get function. - @param[in] Name Pointer to the variable name. - @param[in] Guid Pointer to the vendor GUID. + @param[in] Name Pointer to the variable name. + @param[in] Guid Pointer to the vendor GUID. + @param[in] WildcardMatch Try wildcard match or not. @return Pointer to the property of variable specified by the Name and Guid. **/ VAR_CHECK_VARIABLE_PROPERTY * -InternalVarCheckVariablePropertyGet ( - IN CHAR16 *Name, - IN EFI_GUID *Guid +VariablePropertyGetFunction ( + IN CHAR16 *Name, + IN EFI_GUID *Guid, + IN BOOLEAN WildcardMatch ) { LIST_ENTRY *Link; @@ -1066,27 +1060,23 @@ InternalVarCheckVariablePropertyGet ( CHAR16 *VariableName; VAR_CHECK_VARIABLE_PROPERTY *Property; - Property = NULL; - GetUefiDefinedVariableProperty (Name, Guid, FALSE, &Property, NULL); - if (Property == NULL) { - Property = GetVariableDriverVariableProperty (Name, Guid, NULL); - } - if (Property != NULL) { - return Property; - } else { - for ( Link = GetFirstNode (&mVarCheckVariableList) - ; !IsNull (&mVarCheckVariableList, Link) - ; Link = GetNextNode (&mVarCheckVariableList, Link) - ) { - Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link); - VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry)); - if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) { - return &Entry->VariableProperty; - } + for ( Link = GetFirstNode (&mVarCheckVariableList) + ; !IsNull (&mVarCheckVariableList, Link) + ; Link = GetNextNode (&mVarCheckVariableList, Link) + ) { + Entry = BASE_CR (Link, VAR_CHECK_VARIABLE_ENTRY, Link); + VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry)); + if (CompareGuid (&Entry->Guid, Guid) && (StrCmp (VariableName, Name) == 0)) { + return &Entry->VariableProperty; } } - return NULL; + Property = GetVariableDriverVariableProperty (Name, Guid); + if (Property == NULL) { + GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL); + } + + return Property; } /** @@ -1137,7 +1127,7 @@ VarCheckVariablePropertySet ( AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); - Property = InternalVarCheckVariablePropertyGet (Name, Guid); + Property = VariablePropertyGetFunction (Name, Guid, FALSE); if (Property != NULL) { CopyMem (Property, VariableProperty, sizeof (*VariableProperty)); } else { @@ -1160,20 +1150,19 @@ Done: } /** - Variable property get. + Internal variable property get. @param[in] Name Pointer to the variable name. @param[in] Guid Pointer to the vendor GUID. @param[out] VariableProperty Pointer to the output variable property. @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully. - @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string. @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found. **/ EFI_STATUS EFIAPI -VarCheckVariablePropertyGet ( +InternalVarCheckVariablePropertyGet ( IN CHAR16 *Name, IN EFI_GUID *Guid, OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty @@ -1185,19 +1174,9 @@ VarCheckVariablePropertyGet ( BOOLEAN Found; VAR_CHECK_VARIABLE_PROPERTY *Property; - if (Name == NULL || Name[0] == 0 || Guid == NULL) { - return EFI_INVALID_PARAMETER; - } - - if (VariableProperty == NULL) { - return EFI_INVALID_PARAMETER; - } - Found = FALSE; - AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); - - Property = InternalVarCheckVariablePropertyGet (Name, Guid); + Property = VariablePropertyGetFunction (Name, Guid, TRUE); if (Property != NULL) { CopyMem (VariableProperty, Property, sizeof (*VariableProperty)); Found = TRUE; @@ -1218,8 +1197,45 @@ VarCheckVariablePropertyGet ( } } + return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); +} + +/** + Variable property get. + + @param[in] Name Pointer to the variable name. + @param[in] Guid Pointer to the vendor GUID. + @param[out] VariableProperty Pointer to the output variable property. + + @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully. + @retval EFI_INVALID_PARAMETER Name, Guid or VariableProperty is NULL, or Name is an empty string. + @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found. + +**/ +EFI_STATUS +EFIAPI +VarCheckVariablePropertyGet ( + IN CHAR16 *Name, + IN EFI_GUID *Guid, + OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty + ) +{ + EFI_STATUS Status; + + if (Name == NULL || Name[0] == 0 || Guid == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (VariableProperty == NULL) { + return EFI_INVALID_PARAMETER; + } + + AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); + + Status = InternalVarCheckVariablePropertyGet (Name, Guid, VariableProperty); + ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); - return (Found ? EFI_SUCCESS : EFI_NOT_FOUND); + return Status; } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c index 86e3616e30..7a42d971e0 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c @@ -542,6 +542,218 @@ GetEndPointer ( return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size); } +/** + Record variable error flag. + + @param[in] Flag Variable error flag to record. + @param[in] VariableName Name of variable. + @param[in] VendorGuid Guid of variable. + @param[in] Attributes Attributes of the variable. + @param[in] VariableSize Size of the variable. + +**/ +VOID +RecordVarErrorFlag ( + IN VAR_ERROR_FLAG Flag, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN VariableSize + ) +{ + EFI_STATUS Status; + VARIABLE_POINTER_TRACK Variable; + VAR_ERROR_FLAG *VarErrFlag; + VAR_ERROR_FLAG TempFlag; + + DEBUG_CODE ( + DEBUG ((EFI_D_ERROR, "RecordVarErrorFlag (0x%02x) %s:%g - 0x%08x - 0x%x\n", Flag, VariableName, VendorGuid, Attributes, VariableSize)); + if (Flag == VAR_ERROR_FLAG_SYSTEM_ERROR) { + if (AtRuntime ()) { + DEBUG ((EFI_D_ERROR, "CommonRuntimeVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonRuntimeVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize)); + } else { + DEBUG ((EFI_D_ERROR, "CommonVariableSpace = 0x%x - CommonVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonVariableTotalSize)); + } + } else { + DEBUG ((EFI_D_ERROR, "CommonMaxUserVariableSpace = 0x%x - CommonUserVariableTotalSize = 0x%x\n", mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonUserVariableTotalSize)); + } + ); + + // + // Record error flag (it should have be initialized). + // + Status = FindVariable ( + VAR_ERROR_FLAG_NAME, + &gEdkiiVarErrorFlagGuid, + &Variable, + &mVariableModuleGlobal->VariableGlobal, + FALSE + ); + if (!EFI_ERROR (Status)) { + VarErrFlag = (VAR_ERROR_FLAG *) GetVariableDataPtr (Variable.CurrPtr); + TempFlag = *VarErrFlag; + TempFlag &= Flag; + if (TempFlag == *VarErrFlag) { + return; + } + Status = UpdateVariableStore ( + &mVariableModuleGlobal->VariableGlobal, + FALSE, + FALSE, + mVariableModuleGlobal->FvbInstance, + (UINTN) VarErrFlag - (UINTN) mNvVariableCache + (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, + sizeof (TempFlag), + &TempFlag + ); + if (!EFI_ERROR (Status)) { + // + // Update the data in NV cache. + // + *VarErrFlag = Flag; + } + } +} + +/** + Initialize variable error flag. + + Before EndOfDxe, the variable indicates the last boot variable error flag, + then it means the last boot variable error flag must be got before EndOfDxe. + After EndOfDxe, the variable indicates the current boot variable error flag, + then it means the current boot variable error flag must be got after EndOfDxe. + +**/ +VOID +InitializeVarErrorFlag ( + VOID + ) +{ + EFI_STATUS Status; + VARIABLE_POINTER_TRACK Variable; + VAR_ERROR_FLAG Flag; + VAR_ERROR_FLAG VarErrFlag; + + if (!mEndOfDxe) { + return; + } + + Flag = VAR_ERROR_FLAG_NO_ERROR; + DEBUG ((EFI_D_INFO, "Initialize variable error flag (%02x)\n", Flag)); + + Status = FindVariable ( + VAR_ERROR_FLAG_NAME, + &gEdkiiVarErrorFlagGuid, + &Variable, + &mVariableModuleGlobal->VariableGlobal, + FALSE + ); + if (!EFI_ERROR (Status)) { + VarErrFlag = *((VAR_ERROR_FLAG *) GetVariableDataPtr (Variable.CurrPtr)); + if (VarErrFlag == Flag) { + return; + } + } + + UpdateVariable ( + VAR_ERROR_FLAG_NAME, + &gEdkiiVarErrorFlagGuid, + &Flag, + sizeof (Flag), + VARIABLE_ATTRIBUTE_NV_BS_RT, + 0, + 0, + &Variable, + NULL + ); +} + +/** + Is user variable? + + @param[in] Variable Pointer to variable header. + + @retval TRUE User variable. + @retval FALSE System variable. + +**/ +BOOLEAN +IsUserVariable ( + IN VARIABLE_HEADER *Variable + ) +{ + VAR_CHECK_VARIABLE_PROPERTY Property; + + // + // Only after End Of Dxe, the variables belong to system variable are fixed. + // If PcdMaxUserNvStorageVariableSize is 0, it means user variable share the same NV storage with system variable, + // then no need to check if the variable is user variable or not specially. + // + if (mEndOfDxe && (mVariableModuleGlobal->CommonMaxUserVariableSpace != mVariableModuleGlobal->CommonVariableSpace)) { + if (InternalVarCheckVariablePropertyGet (GetVariableNamePtr (Variable), &Variable->VendorGuid, &Property) == EFI_NOT_FOUND) { + return TRUE; + } + } + return FALSE; +} + +/** + Calculate common user variable total size. + +**/ +VOID +CalculateCommonUserVariableTotalSize ( + VOID + ) +{ + VARIABLE_HEADER *Variable; + VARIABLE_HEADER *NextVariable; + UINTN VariableSize; + VAR_CHECK_VARIABLE_PROPERTY Property; + + // + // Only after End Of Dxe, the variables belong to system variable are fixed. + // If PcdMaxUserNvStorageVariableSize is 0, it means user variable share the same NV storage with system variable, + // then no need to calculate the common user variable total size specially. + // + if (mEndOfDxe && (mVariableModuleGlobal->CommonMaxUserVariableSpace != mVariableModuleGlobal->CommonVariableSpace)) { + Variable = GetStartPointer (mNvVariableCache); + while (IsValidVariableHeader (Variable, GetEndPointer (mNvVariableCache))) { + NextVariable = GetNextVariablePtr (Variable); + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { + if (InternalVarCheckVariablePropertyGet (GetVariableNamePtr (Variable), &Variable->VendorGuid, &Property) == EFI_NOT_FOUND) { + // + // No property, it is user variable. + // + mVariableModuleGlobal->CommonUserVariableTotalSize += VariableSize; + } + } + + Variable = NextVariable; + } + } +} + +/** + Initialize variable quota. + +**/ +VOID +InitializeVariableQuota ( + VOID + ) +{ + STATIC BOOLEAN Initialized; + + if (!mEndOfDxe || Initialized) { + return; + } + Initialized = TRUE; + + InitializeVarErrorFlag (); + CalculateCommonUserVariableTotalSize (); +} + /** Check the PubKeyIndex is a valid key or not. @@ -726,6 +938,7 @@ Reclaim ( BOOLEAN FoundAdded; EFI_STATUS Status; UINTN CommonVariableTotalSize; + UINTN CommonUserVariableTotalSize; UINTN HwErrVariableTotalSize; UINT32 *NewPubKeyIndex; UINT8 *NewPubKeyStore; @@ -744,6 +957,7 @@ Reclaim ( VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINTN) VariableBase); CommonVariableTotalSize = 0; + CommonUserVariableTotalSize = 0; HwErrVariableTotalSize = 0; NewPubKeyIndex = NULL; NewPubKeyStore = NULL; @@ -845,8 +1059,11 @@ Reclaim ( HwErrVariableTotalSize += VariableSize; } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { CommonVariableTotalSize += VariableSize; + if (IsUserVariable (Variable)) { + CommonUserVariableTotalSize += VariableSize; } } + } Variable = NextVariable; } @@ -865,6 +1082,9 @@ Reclaim ( CopyMem (GetVariableDataPtr (Variable), NewPubKeyStore, NewPubKeySize); CurrPtr = (UINT8*) GetNextVariablePtr (Variable); CommonVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable; + if (IsUserVariable (Variable)) { + CommonUserVariableTotalSize += (UINTN) CurrPtr - (UINTN) Variable; + } } else { // // Reinstall all ADDED variables as long as they are not identical to Updating Variable. @@ -880,8 +1100,11 @@ Reclaim ( HwErrVariableTotalSize += VariableSize; } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { CommonVariableTotalSize += VariableSize; + if (IsUserVariable (Variable)) { + CommonUserVariableTotalSize += VariableSize; } } + } Variable = NextVariable; } @@ -928,9 +1151,12 @@ Reclaim ( HwErrVariableTotalSize += VariableSize; } else if ((!IsVolatile) && ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { CommonVariableTotalSize += VariableSize; + if (IsUserVariable (Variable)) { + CommonUserVariableTotalSize += VariableSize; } } } + } Variable = NextVariable; } @@ -951,9 +1177,13 @@ Reclaim ( HwErrVariableTotalSize += NewVariableSize; } else if ((NewVariable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { CommonVariableTotalSize += NewVariableSize; + if (IsUserVariable (NewVariable)) { + CommonUserVariableTotalSize += NewVariableSize; } + } if ((HwErrVariableTotalSize > PcdGet32 (PcdHwErrStorageSize)) || - (CommonVariableTotalSize > VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize))) { + (CommonVariableTotalSize > mVariableModuleGlobal->CommonVariableSpace) || + (CommonUserVariableTotalSize > mVariableModuleGlobal->CommonMaxUserVariableSpace)) { // // No enough space to store the new variable by NV or NV+HR attribute. // @@ -992,19 +1222,24 @@ Reclaim ( *LastVariableOffset = (UINTN) (CurrPtr - ValidBuffer); mVariableModuleGlobal->HwErrVariableTotalSize = HwErrVariableTotalSize; mVariableModuleGlobal->CommonVariableTotalSize = CommonVariableTotalSize; + mVariableModuleGlobal->CommonUserVariableTotalSize = CommonUserVariableTotalSize; } else { - NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); - while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) { - VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); + Variable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase); + while (IsValidVariableHeader (Variable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableBase))) { + NextVariable = GetNextVariablePtr (Variable); + VariableSize = (UINTN) NextVariable - (UINTN) Variable; if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { - mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); + mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize; } else if ((Variable->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != EFI_VARIABLE_HARDWARE_ERROR_RECORD) { - mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); + mVariableModuleGlobal->CommonVariableTotalSize += VariableSize; + if (IsUserVariable (Variable)) { + mVariableModuleGlobal->CommonUserVariableTotalSize += VariableSize; } + } - NextVariable = GetNextVariablePtr (NextVariable); + Variable = NextVariable; } - *LastVariableOffset = (UINTN) NextVariable - (UINTN) VariableBase; + *LastVariableOffset = (UINTN) Variable - (UINTN) VariableBase; } } @@ -1875,7 +2110,6 @@ UpdateVariable ( VARIABLE_HEADER *NextVariable; UINTN ScratchSize; UINTN MaxDataSize; - UINTN NonVolatileVarableStoreSize; UINTN VarNameOffset; UINTN VarDataOffset; UINTN VarNameSize; @@ -1891,6 +2125,8 @@ UpdateVariable ( UINTN MergedBufSize; BOOLEAN DataReady; UINTN DataOffset; + BOOLEAN IsCommonVariable; + BOOLEAN IsCommonUserVariable; if (mVariableModuleGlobal->FvbInstance == NULL) { // @@ -2252,12 +2488,25 @@ UpdateVariable ( // Create a nonvolatile variable. // Volatile = FALSE; - NonVolatileVarableStoreSize = ((VARIABLE_STORE_HEADER *)(UINTN)(mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase))->Size; + + IsCommonVariable = FALSE; + IsCommonUserVariable = FALSE; + if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) { + IsCommonVariable = TRUE; + IsCommonUserVariable = IsUserVariable (NextVariable); + } if ((((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) && ((VarSize + mVariableModuleGlobal->HwErrVariableTotalSize) > PcdGet32 (PcdHwErrStorageSize))) - || (((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == 0) - && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > NonVolatileVarableStoreSize - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize)))) { + || (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonVariableSpace)) + || (IsCommonVariable && AtRuntime () && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonRuntimeVariableSpace)) + || (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace))) { if (AtRuntime ()) { + if (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace)) { + RecordVarErrorFlag (VAR_ERROR_FLAG_USER_ERROR, VariableName, VendorGuid, Attributes, VarSize); + } + if (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonRuntimeVariableSpace)) { + RecordVarErrorFlag (VAR_ERROR_FLAG_SYSTEM_ERROR, VariableName, VendorGuid, Attributes, VarSize); + } Status = EFI_OUT_OF_RESOURCES; goto Done; } @@ -2283,7 +2532,14 @@ UpdateVariable ( } UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRUE, FALSE, FALSE); FlushHobVariableToFlash (VariableName, VendorGuid); + } else { + if (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal->CommonUserVariableTotalSize) > mVariableModuleGlobal->CommonMaxUserVariableSpace)) { + RecordVarErrorFlag (VAR_ERROR_FLAG_USER_ERROR, VariableName, VendorGuid, Attributes, VarSize); } + if (IsCommonVariable && ((VarSize + mVariableModuleGlobal->CommonVariableTotalSize) > mVariableModuleGlobal->CommonVariableSpace)) { + RecordVarErrorFlag (VAR_ERROR_FLAG_SYSTEM_ERROR, VariableName, VendorGuid, Attributes, VarSize); + } + } goto Done; } // @@ -2368,7 +2624,10 @@ UpdateVariable ( mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VarSize); } else { mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VarSize); + if (IsCommonUserVariable) { + mVariableModuleGlobal->CommonUserVariableTotalSize += HEADER_ALIGN (VarSize); } + } // // update the memory copy of Flash region. // @@ -3024,7 +3283,7 @@ VariableServiceSetVariable ( // 2. The only attribute differing is EFI_VARIABLE_APPEND_WRITE // Status = EFI_INVALID_PARAMETER; - DEBUG ((EFI_D_INFO, "[Variable]: Rewritten a preexisting variable with different attributes - %g:%s\n", VendorGuid, VariableName)); + 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)); goto Done; } } @@ -3145,8 +3404,11 @@ VariableServiceQueryVariableInfoInternal ( *MaximumVariableSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER); } else { if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) { - ASSERT (PcdGet32 (PcdHwErrStorageSize) < VariableStoreHeader->Size); - *MaximumVariableStorageSize = VariableStoreHeader->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32 (PcdHwErrStorageSize); + if (AtRuntime ()) { + *MaximumVariableStorageSize = mVariableModuleGlobal->CommonRuntimeVariableSpace; + } else { + *MaximumVariableStorageSize = mVariableModuleGlobal->CommonVariableSpace; + } } // @@ -3222,8 +3484,12 @@ VariableServiceQueryVariableInfoInternal ( if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD){ *RemainingVariableStorageSize = *MaximumVariableStorageSize - HwErrVariableTotalSize; - }else { - *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize; + } else { + if (*MaximumVariableStorageSize < CommonVariableTotalSize) { + *RemainingVariableStorageSize = 0; + } else { + *RemainingVariableStorageSize = *MaximumVariableStorageSize - CommonVariableTotalSize; + } } if (*RemainingVariableStorageSize < sizeof (VARIABLE_HEADER)) { @@ -3271,7 +3537,7 @@ VariableServiceQueryVariableInfo ( return EFI_INVALID_PARAMETER; } - if((Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == 0) { + if ((Attributes & VARIABLE_ATTRIBUTE_NV_BS_RT_AT_HR_AW) == 0) { // // Make sure the Attributes combination is supported by the platform. // @@ -3319,21 +3585,22 @@ ReclaimForOS( ) { EFI_STATUS Status; - UINTN CommonVariableSpace; - UINTN RemainingCommonVariableSpace; + UINTN RemainingCommonRuntimeVariableSpace; UINTN RemainingHwErrVariableSpace; Status = EFI_SUCCESS; - CommonVariableSpace = ((VARIABLE_STORE_HEADER *) ((UINTN) (mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase)))->Size - sizeof (VARIABLE_STORE_HEADER) - PcdGet32(PcdHwErrStorageSize); //Allowable max size of common variable storage space - - RemainingCommonVariableSpace = CommonVariableSpace - mVariableModuleGlobal->CommonVariableTotalSize; + if (mVariableModuleGlobal->CommonRuntimeVariableSpace < mVariableModuleGlobal->CommonVariableTotalSize) { + RemainingCommonRuntimeVariableSpace = 0; + } else { + RemainingCommonRuntimeVariableSpace = mVariableModuleGlobal->CommonRuntimeVariableSpace - mVariableModuleGlobal->CommonVariableTotalSize; + } RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize; // - // Check if the free area is blow a threshold. + // Check if the free area is below a threshold. // - if ((RemainingCommonVariableSpace < PcdGet32 (PcdMaxVariableSize)) + if ((RemainingCommonRuntimeVariableSpace < PcdGet32 (PcdMaxVariableSize)) || ((PcdGet32 (PcdHwErrStorageSize) != 0) && (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){ Status = Reclaim ( @@ -3363,6 +3630,7 @@ InitNonVolatileVariableStore ( ) { EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + VARIABLE_HEADER *Variable; VARIABLE_HEADER *NextVariable; EFI_PHYSICAL_ADDRESS VariableStoreBase; UINT64 VariableStoreLength; @@ -3374,17 +3642,12 @@ InitNonVolatileVariableStore ( FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; UINT32 BackUpOffset; UINT32 BackUpSize; + UINT32 HwErrStorageSize; + UINT32 MaxUserNvVariableSpaceSize; + UINT32 BoottimeReservedNvVariableSpaceSize; mVariableModuleGlobal->FvbInstance = NULL; - // - // Note that in EdkII variable driver implementation, Hardware Error Record type variable - // is stored with common variable in the same NV region. So the platform integrator should - // ensure that the value of PcdHwErrStorageSize is less than or equal to the value of - // PcdFlashNvStorageVariableSize. - // - ASSERT (PcdGet32 (PcdHwErrStorageSize) <= PcdGet32 (PcdFlashNvStorageVariableSize)); - // // Allocate runtime memory used for a memory copy of the FLASH region. // Keep the memory and the FLASH in sync as updates occur. @@ -3454,6 +3717,37 @@ InitNonVolatileVariableStore ( } ASSERT(mNvVariableCache->Size == VariableStoreLength); + + ASSERT (sizeof (VARIABLE_STORE_HEADER) <= VariableStoreLength); + + HwErrStorageSize = PcdGet32 (PcdHwErrStorageSize); + MaxUserNvVariableSpaceSize = PcdGet32 (PcdMaxUserNvVariableSpaceSize); + BoottimeReservedNvVariableSpaceSize = PcdGet32 (PcdBoottimeReservedNvVariableSpaceSize); + + // + // Note that in EdkII variable driver implementation, Hardware Error Record type variable + // is stored with common variable in the same NV region. So the platform integrator should + // ensure that the value of PcdHwErrStorageSize is less than the value of + // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)). + // + ASSERT (HwErrStorageSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER))); + // + // Ensure that the value of PcdMaxUserNvVariableSpaceSize is less than the value of + // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize). + // + ASSERT (MaxUserNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize)); + // + // Ensure that the value of PcdBoottimeReservedNvVariableSpaceSize is less than the value of + // VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize). + // + ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize)); + + mVariableModuleGlobal->CommonVariableSpace = ((UINTN) VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize); + mVariableModuleGlobal->CommonMaxUserVariableSpace = ((MaxUserNvVariableSpaceSize != 0) ? MaxUserNvVariableSpaceSize : mVariableModuleGlobal->CommonVariableSpace); + mVariableModuleGlobal->CommonRuntimeVariableSpace = mVariableModuleGlobal->CommonVariableSpace - BoottimeReservedNvVariableSpaceSize; + + DEBUG ((EFI_D_INFO, "Variable driver common space: 0x%x 0x%x 0x%x\n", mVariableModuleGlobal->CommonVariableSpace, mVariableModuleGlobal->CommonMaxUserVariableSpace, mVariableModuleGlobal->CommonRuntimeVariableSpace)); + // // The max variable or hardware error variable size should be < variable store size. // @@ -3462,18 +3756,19 @@ InitNonVolatileVariableStore ( // // Parse non-volatile variable data and get last variable offset. // - NextVariable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase); - while (IsValidVariableHeader (NextVariable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase))) { - VariableSize = NextVariable->NameSize + NextVariable->DataSize + sizeof (VARIABLE_HEADER); - if ((NextVariable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { - mVariableModuleGlobal->HwErrVariableTotalSize += HEADER_ALIGN (VariableSize); + Variable = GetStartPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase); + while (IsValidVariableHeader (Variable, GetEndPointer ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase))) { + NextVariable = GetNextVariablePtr (Variable); + VariableSize = (UINTN) NextVariable - (UINTN) Variable; + if ((Variable->Attributes & (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) == (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_HARDWARE_ERROR_RECORD)) { + mVariableModuleGlobal->HwErrVariableTotalSize += VariableSize; } else { - mVariableModuleGlobal->CommonVariableTotalSize += HEADER_ALIGN (VariableSize); + mVariableModuleGlobal->CommonVariableTotalSize += VariableSize; } - NextVariable = GetNextVariablePtr (NextVariable); + Variable = NextVariable; } - mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) NextVariable - (UINTN) VariableStoreBase; + mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN) Variable - (UINTN) VariableStoreBase; return EFI_SUCCESS; } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h index 8591001f8b..f86b202fda 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h @@ -44,6 +44,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include #include +#include #define EFI_VARIABLE_ATTRIBUTES_MASK (EFI_VARIABLE_NON_VOLATILE | \ EFI_VARIABLE_BOOTSERVICE_ACCESS | \ @@ -59,7 +60,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define VARIABLE_ATTRIBUTE_NV_BS_RT_AT (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) #define VARIABLE_ATTRIBUTE_NV_BS_RT_HR (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_HARDWARE_ERROR_RECORD) #define VARIABLE_ATTRIBUTE_NV_BS_RT_AW (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) - +#define VARIABLE_ATTRIBUTE_NV_BS_RT_AT_HR_AW (VARIABLE_ATTRIBUTE_NV_BS_RT_AT | EFI_VARIABLE_HARDWARE_ERROR_RECORD | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) + /// /// The size of a 3 character ISO639 language code. /// @@ -98,7 +100,11 @@ typedef struct { VARIABLE_GLOBAL VariableGlobal; UINTN VolatileLastVariableOffset; UINTN NonVolatileLastVariableOffset; + UINTN CommonVariableSpace; + UINTN CommonMaxUserVariableSpace; + UINTN CommonRuntimeVariableSpace; UINTN CommonVariableTotalSize; + UINTN CommonUserVariableTotalSize; UINTN HwErrVariableTotalSize; CHAR8 *PlatformLangCodes; CHAR8 *LangCodes; @@ -735,6 +741,25 @@ VarCheckRegisterSetVariableCheckHandler ( IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler ); +/** + Internal variable property get. + + @param[in] Name Pointer to the variable name. + @param[in] Guid Pointer to the vendor GUID. + @param[out] VariableProperty Pointer to the output variable property. + + @retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully. + @retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found. + +**/ +EFI_STATUS +EFIAPI +InternalVarCheckVariablePropertyGet ( + IN CHAR16 *Name, + IN EFI_GUID *Guid, + OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty + ); + /** Variable property set. @@ -778,6 +803,15 @@ VarCheckVariablePropertyGet ( OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty ); +/** + Initialize variable quota. + +**/ +VOID +InitializeVariableQuota ( + VOID + ); + extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal; #endif diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c index a1352510eb..375a604df2 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c @@ -286,6 +286,10 @@ OnReadyToBoot ( // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event is not signaled. // mEndOfDxe = TRUE; + // + // The initialization for variable quota. + // + InitializeVariableQuota (); ReclaimForOS (); if (FeaturePcdGet (PcdVariableCollectStatistics)) { gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo); @@ -309,6 +313,10 @@ OnEndOfDxe ( ) { mEndOfDxe = TRUE; + // + // The initialization for variable quota. + // + InitializeVariableQuota (); } /** diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf index 8a8d4adef5..4e31178e16 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf @@ -132,6 +132,7 @@ gEfiSystemNvDataFvGuid ## CONSUMES ## GUID gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES ## Variable:L"HwErrRec####" gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB + gEdkiiVarErrorFlagGuid ## CONSUMES ## GUID [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES @@ -141,6 +142,8 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize ## CONSUMES [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c index dd1f794cff..9af9eafe14 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c @@ -716,6 +716,10 @@ SmmVariableHandler ( case SMM_VARIABLE_FUNCTION_READY_TO_BOOT: mEndOfDxe = TRUE; + // + // The initialization for variable quota. + // + InitializeVariableQuota (); if (AtRuntime()) { Status = EFI_UNSUPPORTED; break; @@ -846,6 +850,10 @@ SmmEndOfDxeCallback ( { DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n")); mEndOfDxe = TRUE; + // + // The initialization for variable quota. + // + InitializeVariableQuota (); return EFI_SUCCESS; } diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf index a7d0505e21..ec4249a95f 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf @@ -139,7 +139,8 @@ gEfiSystemNvDataFvGuid ## CONSUMES ## GUID gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES ## Variable:L"HwErrRec####" gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB - + gEdkiiVarErrorFlagGuid ## CONSUMES ## GUID + [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES @@ -148,7 +149,9 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES - + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize ## CONSUMES + [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang -- 2.39.2