Calculate enough space for 2 variables (public key and variable data) instead of directly setting them 1 by 1.

Fixed a bug in public key reclaim().

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Dong Guo <guo.dong@intel.com>
Reviewed-by: Yao Jiewen <jiewen.yao@intel.com>
Reviewed-by: Zeng, Star <star.zeng@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15404 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Dong Guo 2014-03-27 10:54:23 +00:00 committed by gdong1
parent 2c775600d5
commit 9a12e5825a
5 changed files with 106 additions and 75 deletions

View File

@ -1268,8 +1268,10 @@ VariableGetBestLanguage (
so follow the argument sequence to check the Variables. so follow the argument sequence to check the Variables.
@param[in] Attributes Variable attributes for Variable entries. @param[in] Attributes Variable attributes for Variable entries.
@param ... Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *. @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
A NULL terminates the list. A NULL terminates the list. The VariableSize of
VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
It will be changed to variable total size as output.
@retval TRUE Have enough variable space to set the Variables successfully. @retval TRUE Have enough variable space to set the Variables successfully.
@retval FALSE No enough variable space to set the Variables successfully. @retval FALSE No enough variable space to set the Variables successfully.
@ -1293,6 +1295,8 @@ CheckRemainingSpaceForConsistency (
VARIABLE_STORE_HEADER *VariableStoreHeader; VARIABLE_STORE_HEADER *VariableStoreHeader;
VARIABLE_POINTER_TRACK VariablePtrTrack; VARIABLE_POINTER_TRACK VariablePtrTrack;
VARIABLE_HEADER *NextVariable; VARIABLE_HEADER *NextVariable;
UINTN VarNameSize;
UINTN VarDataSize;
// //
// Non-Volatile related. // Non-Volatile related.
@ -1311,6 +1315,15 @@ CheckRemainingSpaceForConsistency (
VA_START (Args, Attributes); VA_START (Args, Attributes);
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
while (VariableEntry != NULL) { while (VariableEntry != NULL) {
//
// Calculate variable total size.
//
VarNameSize = StrSize (VariableEntry->Name);
VarNameSize += GET_PAD_SIZE (VarNameSize);
VarDataSize = VariableEntry->VariableSize;
VarDataSize += GET_PAD_SIZE (VarDataSize);
VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize);
TotalNeededSize += VariableEntry->VariableSize; TotalNeededSize += VariableEntry->VariableSize;
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
} }
@ -1407,8 +1420,6 @@ AutoUpdateLangVariable (
UINT32 Attributes; UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable; VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes; BOOLEAN SetLanguageCodes;
UINTN VarNameSize;
UINTN VarDataSize;
VARIABLE_ENTRY_CONSISTENCY VariableEntry[2]; VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
// //
@ -1532,21 +1543,13 @@ AutoUpdateLangVariable (
BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE); BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);
// //
// Calculate the needed variable size for Lang variable. // Check the variable space for both Lang and PlatformLang variable.
// //
VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME); VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME; VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for PlatformLang variable. VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);
//
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
@ -1589,21 +1592,13 @@ AutoUpdateLangVariable (
BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE); BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
// //
// Calculate the needed variable size for PlatformLang variable. // Check the variable space for both PlatformLang and Lang variable.
// //
VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME); VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang);
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for Lang variable. VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
//
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME; VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {

View File

@ -101,10 +101,6 @@ typedef struct {
typedef struct { typedef struct {
EFI_GUID *Guid; EFI_GUID *Guid;
CHAR16 *Name; CHAR16 *Name;
// UINT32 Attributes;
//
// Variable size include variable header, name and data.
//
UINTN VariableSize; UINTN VariableSize;
} VARIABLE_ENTRY_CONSISTENCY; } VARIABLE_ENTRY_CONSISTENCY;

View File

@ -456,7 +456,8 @@ AutenticatedVariableServiceInitialize (
**/ **/
UINT32 UINT32
AddPubKeyInStore ( AddPubKeyInStore (
IN UINT8 *PubKey IN UINT8 *PubKey,
IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -466,6 +467,8 @@ AddPubKeyInStore (
UINT8 *Ptr; UINT8 *Ptr;
UINT8 *Data; UINT8 *Data;
UINTN DataSize; UINTN DataSize;
VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry;
UINT32 Attributes;
if (PubKey == NULL) { if (PubKey == NULL) {
return 0; return 0;
@ -546,6 +549,21 @@ AddPubKeyInStore (
} }
} }
//
// Check the variable space for both public key and variable data.
//
PublicKeyEntry.VariableSize = (mPubKeyNumber + 1) * EFI_CERT_TYPE_RSA2048_SIZE;
PublicKeyEntry.Guid = &gEfiAuthenticatedVariableGuid;
PublicKeyEntry.Name = AUTHVAR_KEYDB_NAME;
Attributes = VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS;
if (!CheckRemainingSpaceForConsistency (Attributes, &PublicKeyEntry, VariableDataEntry, NULL)) {
//
// No enough variable space.
//
return 0;
}
CopyMem (mPubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE); CopyMem (mPubKeyStore + mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, PubKey, EFI_CERT_TYPE_RSA2048_SIZE);
Index = ++mPubKeyNumber; Index = ++mPubKeyNumber;
// //
@ -556,7 +574,7 @@ AddPubKeyInStore (
&gEfiAuthenticatedVariableGuid, &gEfiAuthenticatedVariableGuid,
mPubKeyStore, mPubKeyStore,
mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE, mPubKeyNumber * EFI_CERT_TYPE_RSA2048_SIZE,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, Attributes,
0, 0,
0, 0,
&Variable, &Variable,
@ -1271,6 +1289,7 @@ ProcessVariable (
EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock; EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
UINT32 KeyIndex; UINT32 KeyIndex;
UINT64 MonotonicCount; UINT64 MonotonicCount;
VARIABLE_ENTRY_CONSISTENCY VariableDataEntry;
KeyIndex = 0; KeyIndex = 0;
CertData = NULL; CertData = NULL;
@ -1396,10 +1415,14 @@ ProcessVariable (
// Now, the signature has been verified! // Now, the signature has been verified!
// //
if (IsFirstTime && !IsDeletion) { if (IsFirstTime && !IsDeletion) {
VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE;
VariableDataEntry.Guid = VendorGuid;
VariableDataEntry.Name = VariableName;
// //
// Update public key database variable if need. // Update public key database variable if need.
// //
KeyIndex = AddPubKeyInStore (PubKey); KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry);
if (KeyIndex == 0) { if (KeyIndex == 0) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }

View File

@ -610,7 +610,7 @@ IsValidPubKeyIndex (
return FALSE; return FALSE;
} }
Variable = GetStartPointer (mNvVariableCache); Variable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
while (IsValidVariableHeader (Variable)) { while (IsValidVariableHeader (Variable)) {
if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) && if ((Variable->State == VAR_ADDED || Variable->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) &&
@ -1518,8 +1518,10 @@ VariableGetBestLanguage (
so follow the argument sequence to check the Variables. so follow the argument sequence to check the Variables.
@param[in] Attributes Variable attributes for Variable entries. @param[in] Attributes Variable attributes for Variable entries.
@param ... Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *. @param ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
A NULL terminates the list. A NULL terminates the list. The VariableSize of
VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
It will be changed to variable total size as output.
@retval TRUE Have enough variable space to set the Variables successfully. @retval TRUE Have enough variable space to set the Variables successfully.
@retval FALSE No enough variable space to set the Variables successfully. @retval FALSE No enough variable space to set the Variables successfully.
@ -1543,6 +1545,8 @@ CheckRemainingSpaceForConsistency (
VARIABLE_STORE_HEADER *VariableStoreHeader; VARIABLE_STORE_HEADER *VariableStoreHeader;
VARIABLE_POINTER_TRACK VariablePtrTrack; VARIABLE_POINTER_TRACK VariablePtrTrack;
VARIABLE_HEADER *NextVariable; VARIABLE_HEADER *NextVariable;
UINTN VarNameSize;
UINTN VarDataSize;
// //
// Non-Volatile related. // Non-Volatile related.
@ -1561,6 +1565,15 @@ CheckRemainingSpaceForConsistency (
VA_START (Args, Attributes); VA_START (Args, Attributes);
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
while (VariableEntry != NULL) { while (VariableEntry != NULL) {
//
// Calculate variable total size.
//
VarNameSize = StrSize (VariableEntry->Name);
VarNameSize += GET_PAD_SIZE (VarNameSize);
VarDataSize = VariableEntry->VariableSize;
VarDataSize += GET_PAD_SIZE (VarDataSize);
VariableEntry->VariableSize = HEADER_ALIGN (sizeof (VARIABLE_HEADER) + VarNameSize + VarDataSize);
TotalNeededSize += VariableEntry->VariableSize; TotalNeededSize += VariableEntry->VariableSize;
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *); VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
} }
@ -1657,8 +1670,6 @@ AutoUpdateLangVariable (
UINT32 Attributes; UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable; VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes; BOOLEAN SetLanguageCodes;
UINTN VarNameSize;
UINTN VarDataSize;
VARIABLE_ENTRY_CONSISTENCY VariableEntry[2]; VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
// //
@ -1782,21 +1793,13 @@ AutoUpdateLangVariable (
BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE); BestLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->LangCodes, Index, TRUE);
// //
// Calculate the needed variable size for Lang variable. // Check the variable space for both Lang and PlatformLang variable.
// //
VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME); VariableEntry[0].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME; VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for PlatformLang variable. VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);
//
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
@ -1839,21 +1842,13 @@ AutoUpdateLangVariable (
BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE); BestPlatformLang = GetLangFromSupportedLangCodes (mVariableModuleGlobal->PlatformLangCodes, Index, FALSE);
// //
// Calculate the needed variable size for PlatformLang variable. // Check the variable space for both PlatformLang and Lang variable.
// //
VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME); VariableEntry[0].VariableSize = AsciiStrSize (BestPlatformLang);
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME; VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for Lang variable. VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
//
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].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME; VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) { if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {

View File

@ -111,10 +111,6 @@ typedef struct {
typedef struct { typedef struct {
EFI_GUID *Guid; EFI_GUID *Guid;
CHAR16 *Name; CHAR16 *Name;
// UINT32 Attributes;
//
// Variable size include variable header, name and data.
//
UINTN VariableSize; UINTN VariableSize;
} VARIABLE_ENTRY_CONSISTENCY; } VARIABLE_ENTRY_CONSISTENCY;
@ -221,6 +217,32 @@ DataSizeOfVariable (
IN VARIABLE_HEADER *Variable IN VARIABLE_HEADER *Variable
); );
/**
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 ... The variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
A NULL terminates the list. The VariableSize of
VARIABLE_ENTRY_CONSISTENCY is the variable data size as input.
It will be changed to variable total size as output.
@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,
...
);
/** /**
Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set, Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set,
index of associated public key is needed. index of associated public key is needed.