1. If PcdMaxAuthVariableSize is set to 0, keep current behavior as is and PcdMaxVariableSize used. 2. If PcdMaxAuthVariableSize is set to non 0, it will work on authenticated variables.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.z...@intel.com> --- .../VariableAuthenticated/RuntimeDxe/AuthService.c | 11 ++-- .../VariableAuthenticated/RuntimeDxe/AuthService.h | 9 +++- .../VariableAuthenticated/RuntimeDxe/Variable.c | 60 ++++++++++++++-------- .../VariableAuthenticated/RuntimeDxe/Variable.h | 8 +++ .../RuntimeDxe/VariableRuntimeDxe.inf | 1 + .../VariableAuthenticated/RuntimeDxe/VariableSmm.c | 2 +- .../RuntimeDxe/VariableSmm.inf | 3 +- .../RuntimeDxe/VariableSmmRuntimeDxe.c | 6 ++- .../RuntimeDxe/VariableSmmRuntimeDxe.inf | 1 + 9 files changed, 73 insertions(+), 28 deletions(-) diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c index 36d4470..9599c8a 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.c @@ -124,13 +124,18 @@ InCustomMode ( /** Initializes for authenticated varibale service. + @param[in] MaxAuthVariableSize Reflect the overhead associated with the saving + of a single EFI authenticated variable with the exception + of the overhead associated with the length + of the string name of the EFI variable. + @retval EFI_SUCCESS Function successfully executed. @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resources. **/ EFI_STATUS AutenticatedVariableServiceInitialize ( - VOID + IN UINTN MaxAuthVariableSize ) { EFI_STATUS Status; @@ -158,7 +163,7 @@ AutenticatedVariableServiceInitialize ( // // Reserve runtime buffer for public key database. The size excludes variable header and name size. // - mMaxKeyDbSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - sizeof (AUTHVAR_KEYDB_NAME); + mMaxKeyDbSize = (UINT32) (MaxAuthVariableSize - sizeof (AUTHVAR_KEYDB_NAME)); mMaxKeyNumber = mMaxKeyDbSize / EFI_CERT_TYPE_RSA2048_SIZE; mPubKeyStore = AllocateRuntimePool (mMaxKeyDbSize); if (mPubKeyStore == NULL) { @@ -168,7 +173,7 @@ AutenticatedVariableServiceInitialize ( // // Reserve runtime buffer for certificate database. The size excludes variable header and name size. // - mMaxCertDbSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER) - sizeof (EFI_CERT_DB_NAME); + mMaxCertDbSize = (UINT32) (MaxAuthVariableSize - sizeof (EFI_CERT_DB_NAME)); mCertDbStore = AllocateRuntimePool (mMaxCertDbSize); if (mCertDbStore == NULL) { return EFI_OUT_OF_RESOURCES; diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h index f28c825..56def50 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/AuthService.h @@ -139,13 +139,18 @@ UpdatePlatformMode ( /** Initializes for authenticated varibale service. + @param[in] MaxAuthVariableSize Reflect the overhead associated with the saving + of a single EFI authenticated variable with the exception + of the overhead associated with the length + of the string name of the EFI variable. + @retval EFI_SUCCESS Function successfully executed. - @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resource. + @retval EFI_OUT_OF_RESOURCES Fail to allocate enough memory resources. **/ EFI_STATUS AutenticatedVariableServiceInitialize ( - VOID + IN UINTN MaxAuthVariableSize ); /** diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c index 7ecc29b..15d0531 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c @@ -2153,7 +2153,7 @@ UpdateVariable ( // Trying to update NV variable prior to the installation of EFI_VARIABLE_WRITE_ARCH_PROTOCOL // return EFI_NOT_AVAILABLE_YET; - } else if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { + } else if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) { // // Trying to update volatile authenticated variable prior to the installation of EFI_VARIABLE_WRITE_ARCH_PROTOCOL // The authenticated variable perhaps is not initialized, just return here. @@ -2190,7 +2190,7 @@ UpdateVariable ( // as a temporary storage. // NextVariable = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase)); - ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)); + ScratchSize = mVariableModuleGlobal->ScratchBufferSize; SetMem (NextVariable, ScratchSize, 0xff); DataReady = FALSE; @@ -2309,9 +2309,13 @@ UpdateVariable ( CopyMem (BufferForMerge, (UINT8 *) ((UINTN) Variable->CurrPtr + DataOffset), Variable->CurrPtr->DataSize); // - // Set Max Common Variable Data Size as default MaxDataSize + // Set Max Common/Auth Variable Data Size as default MaxDataSize // - MaxDataSize = PcdGet32 (PcdMaxVariableSize) - DataOffset; + if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) { + MaxDataSize = mVariableModuleGlobal->MaxAuthVariableSize - DataOffset; + } else { + MaxDataSize = mVariableModuleGlobal->MaxVariableSize - DataOffset; + } if ((CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid) && ((StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE) == 0) || (StrCmp (VariableName, EFI_IMAGE_SECURITY_DATABASE1) == 0) || @@ -2351,7 +2355,7 @@ UpdateVariable ( } else { // // For other Variables, append the new data to the end of existing data. - // Max Harware error record variable data size is different from common variable + // Max Harware error record variable data size is different from common/auth variable // if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - DataOffset; @@ -3237,7 +3241,7 @@ VariableServiceSetVariable ( // // The size of the VariableName, including the Unicode Null in bytes plus // the DataSize is limited to maximum size of PcdGet32 (PcdMaxHardwareErrorVariableSize) - // bytes for HwErrRec, and PcdGet32 (PcdMaxVariableSize) bytes for the others. + // bytes for HwErrRec. // if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) == EFI_VARIABLE_HARDWARE_ERROR_RECORD) { if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxHardwareErrorVariableSize) - sizeof (VARIABLE_HEADER)) { @@ -3249,10 +3253,16 @@ VariableServiceSetVariable ( } else { // // The size of the VariableName, including the Unicode Null in bytes plus - // the DataSize is limited to maximum size of PcdGet32 (PcdMaxVariableSize) bytes. + // the DataSize is limited to maximum size of Max(Auth)VariableSize bytes. // - if (StrSize (VariableName) + PayloadSize > PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER)) { - return EFI_INVALID_PARAMETER; + if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) { + if (StrSize (VariableName) + PayloadSize > mVariableModuleGlobal->MaxAuthVariableSize - sizeof (VARIABLE_HEADER)) { + return EFI_INVALID_PARAMETER; + } + } else { + if (StrSize (VariableName) + PayloadSize > mVariableModuleGlobal->MaxVariableSize - sizeof (VARIABLE_HEADER)) { + return EFI_INVALID_PARAMETER; + } } } @@ -3442,9 +3452,13 @@ VariableServiceQueryVariableInfoInternal ( } // - // Let *MaximumVariableSize be PcdGet32 (PcdMaxVariableSize) with the exception of the variable header size. + // Let *MaximumVariableSize be Max(Auth)VariableSize with the exception of the variable header size. // - *MaximumVariableSize = PcdGet32 (PcdMaxVariableSize) - sizeof (VARIABLE_HEADER); + if ((Attributes & VARIABLE_ATTRIBUTE_AT_AW) != 0) { + *MaximumVariableSize = mVariableModuleGlobal->MaxAuthVariableSize - sizeof (VARIABLE_HEADER); + } else { + *MaximumVariableSize = mVariableModuleGlobal->MaxVariableSize - sizeof (VARIABLE_HEADER); + } } // @@ -3636,11 +3650,13 @@ ReclaimForOS( } RemainingHwErrVariableSpace = PcdGet32 (PcdHwErrStorageSize) - mVariableModuleGlobal->HwErrVariableTotalSize; + // // Check if the free area is below a threshold. // - if ((RemainingCommonRuntimeVariableSpace < PcdGet32 (PcdMaxVariableSize)) - || ((PcdGet32 (PcdHwErrStorageSize) != 0) && + if (((RemainingCommonRuntimeVariableSpace < mVariableModuleGlobal->MaxVariableSize) || + (RemainingCommonRuntimeVariableSpace < mVariableModuleGlobal->MaxAuthVariableSize)) || + ((PcdGet32 (PcdHwErrStorageSize) != 0) && (RemainingHwErrVariableSpace < PcdGet32 (PcdMaxHardwareErrorVariableSize)))){ Status = Reclaim ( mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase, @@ -3767,17 +3783,17 @@ InitNonVolatileVariableStore ( // 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)). + // (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). + // (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). + // (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) - PcdGet32 (PcdHwErrStorageSize). // ASSERT (BoottimeReservedNvVariableSpaceSize < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER) - HwErrStorageSize)); @@ -3788,9 +3804,12 @@ InitNonVolatileVariableStore ( 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. + // The max NV variable size should be < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)). // - ASSERT(MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) < VariableStoreLength); + ASSERT (MAX_NV_VARIABLE_SIZE < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER))); + + mVariableModuleGlobal->MaxVariableSize = PcdGet32 (PcdMaxVariableSize); + mVariableModuleGlobal->MaxAuthVariableSize = ((PcdGet32 (PcdMaxAuthVariableSize) != 0) ? PcdGet32 (PcdMaxAuthVariableSize) : mVariableModuleGlobal->MaxVariableSize); // // Parse non-volatile variable data and get last variable offset. @@ -3963,7 +3982,7 @@ VariableWriteServiceInitialize ( // // Authenticated variable initialize. // - Status = AutenticatedVariableServiceInitialize (); + Status = AutenticatedVariableServiceInitialize (mVariableModuleGlobal->MaxAuthVariableSize - sizeof (VARIABLE_HEADER)); return Status; } @@ -4019,7 +4038,8 @@ VariableCommonInitialize ( // // Allocate memory for volatile variable store, note that there is a scratch space to store scratch data. // - ScratchSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)); + ScratchSize = MAX_NV_VARIABLE_SIZE; + mVariableModuleGlobal->ScratchBufferSize = ScratchSize; VolatileVariableStore = AllocateRuntimePool (PcdGet32 (PcdVariableStoreSize) + ScratchSize); if (VolatileVariableStore == NULL) { if (mVariableModuleGlobal->VariableGlobal.HobVariableBase != 0) { diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h index fd4dab2..4a4595f 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h @@ -61,6 +61,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #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) +#define VARIABLE_ATTRIBUTE_AT_AW (EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) + +#define MAX_NV_VARIABLE_SIZE (MAX (MAX (PcdGet32 (PcdMaxVariableSize), \ + PcdGet32 (PcdMaxAuthVariableSize)), \ + PcdGet32 (PcdMaxHardwareErrorVariableSize))) /// /// The size of a 3 character ISO639 language code. @@ -106,6 +111,9 @@ typedef struct { UINTN CommonVariableTotalSize; UINTN CommonUserVariableTotalSize; UINTN HwErrVariableTotalSize; + UINTN MaxVariableSize; + UINTN MaxAuthVariableSize; + UINTN ScratchBufferSize; CHAR8 *PlatformLangCodes; CHAR8 *LangCodes; CHAR8 *PlatformLang; diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf index cbf7da0..2b1b1c0 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf @@ -139,6 +139,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c index a1ac461..1eb169a 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c @@ -932,7 +932,7 @@ VariableServiceInitialize ( ); ASSERT_EFI_ERROR (Status); - mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) + + mVariableBufferPayloadSize = MAX_NV_VARIABLE_SIZE + OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER); Status = gSmst->SmmAllocatePool ( diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf index efb80f3..00181db 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf @@ -146,6 +146,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES @@ -161,4 +162,4 @@ TRUE [UserExtensions.TianoCore."ExtraFiles"] - VariableSmmExtra.uni \ No newline at end of file + VariableSmmExtra.uni diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c index e87e12f..94b60bf 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c @@ -59,6 +59,10 @@ EFI_LOCK mVariableServicesLock; EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock; EDKII_VAR_CHECK_PROTOCOL mVarCheck; +#define MAX_NV_VARIABLE_SIZE (MAX (MAX (PcdGet32 (PcdMaxVariableSize), \ + PcdGet32 (PcdMaxAuthVariableSize)), \ + PcdGet32 (PcdMaxHardwareErrorVariableSize))) + /** SecureBoot Hook for SetVariable. @@ -931,7 +935,7 @@ SmmVariableReady ( // // Allocate memory for variable communicate buffer. // - mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) + + mVariableBufferPayloadSize = MAX_NV_VARIABLE_SIZE + OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER); mVariableBufferSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + mVariableBufferPayloadSize; mVariableBuffer = AllocateRuntimePool (mVariableBufferSize); diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf index e48a0f1..db6a4de 100644 --- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf +++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf @@ -92,6 +92,7 @@ [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES [Depex] -- 1.9.5.msysgit.0 ------------------------------------------------------------------------------ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel