From 13af4ab06516eefb40fb985467141e09efe9c58b Mon Sep 17 00:00:00 2001 From: Star Zeng Date: Wed, 10 Jun 2015 07:52:12 +0000 Subject: [PATCH] SecurityPkg Variable: Support the new introduced PcdMaxAuthVariableSize. 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 Reviewed-by: Jiewen Yao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17610 6f19259b-4bc3-4df7-8a09-765794883524 --- .../RuntimeDxe/AuthService.c | 11 +++- .../RuntimeDxe/AuthService.h | 9 ++- .../RuntimeDxe/Variable.c | 60 ++++++++++++------- .../RuntimeDxe/Variable.h | 8 +++ .../RuntimeDxe/VariableRuntimeDxe.inf | 1 + .../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 36d447027d..9599c8a6d8 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 f28c82578e..56def50d52 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 7ecc29b94b..15d053186c 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 fd4dab2429..4a4595fe4c 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 cbf7da0add..2b1b1c0b58 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 a1ac461542..1eb169ac6e 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 efb80f3665..00181dbea8 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 e87e12fc99..94b60bf5cf 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 e48a0f16f6..db6a4de6ab 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] -- 2.39.2