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.
@param[in] Attributes Variable attributes for Variable entries.
@param ... Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
A NULL terminates the list.
@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.
@ -1293,6 +1295,8 @@ CheckRemainingSpaceForConsistency (
VARIABLE_STORE_HEADER *VariableStoreHeader;
VARIABLE_POINTER_TRACK VariablePtrTrack;
VARIABLE_HEADER *NextVariable;
UINTN VarNameSize;
UINTN VarDataSize;
//
// Non-Volatile related.
@ -1311,6 +1315,15 @@ CheckRemainingSpaceForConsistency (
VA_START (Args, Attributes);
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
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;
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
}
@ -1407,8 +1420,6 @@ AutoUpdateLangVariable (
UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes;
UINTN VarNameSize;
UINTN VarDataSize;
VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
//
@ -1532,21 +1543,13 @@ AutoUpdateLangVariable (
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);
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].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for PlatformLang variable.
//
VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
VarDataSize = AsciiStrSize (BestPlatformLang);
VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);
VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
@ -1589,21 +1592,13 @@ AutoUpdateLangVariable (
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);
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].VariableSize = AsciiStrSize (BestPlatformLang);
VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for Lang variable.
//
VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {

View File

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

View File

@ -456,16 +456,19 @@ AutenticatedVariableServiceInitialize (
**/
UINT32
AddPubKeyInStore (
IN UINT8 *PubKey
IN UINT8 *PubKey,
IN VARIABLE_ENTRY_CONSISTENCY *VariableDataEntry
)
{
EFI_STATUS Status;
BOOLEAN IsFound;
UINT32 Index;
VARIABLE_POINTER_TRACK Variable;
UINT8 *Ptr;
UINT8 *Data;
UINTN DataSize;
EFI_STATUS Status;
BOOLEAN IsFound;
UINT32 Index;
VARIABLE_POINTER_TRACK Variable;
UINT8 *Ptr;
UINT8 *Data;
UINTN DataSize;
VARIABLE_ENTRY_CONSISTENCY PublicKeyEntry;
UINT32 Attributes;
if (PubKey == NULL) {
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);
Index = ++mPubKeyNumber;
//
@ -556,7 +574,7 @@ AddPubKeyInStore (
&gEfiAuthenticatedVariableGuid,
mPubKeyStore,
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,
&Variable,
@ -1271,6 +1289,7 @@ ProcessVariable (
EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
UINT32 KeyIndex;
UINT64 MonotonicCount;
VARIABLE_ENTRY_CONSISTENCY VariableDataEntry;
KeyIndex = 0;
CertData = NULL;
@ -1396,10 +1415,14 @@ ProcessVariable (
// Now, the signature has been verified!
//
if (IsFirstTime && !IsDeletion) {
VariableDataEntry.VariableSize = DataSize - AUTHINFO_SIZE;
VariableDataEntry.Guid = VendorGuid;
VariableDataEntry.Name = VariableName;
//
// Update public key database variable if need.
//
KeyIndex = AddPubKeyInStore (PubKey);
KeyIndex = AddPubKeyInStore (PubKey, &VariableDataEntry);
if (KeyIndex == 0) {
return EFI_OUT_OF_RESOURCES;
}

View File

@ -610,7 +610,7 @@ IsValidPubKeyIndex (
return FALSE;
}
Variable = GetStartPointer (mNvVariableCache);
Variable = GetStartPointer ((VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
while (IsValidVariableHeader (Variable)) {
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.
@param[in] Attributes Variable attributes for Variable entries.
@param ... Variable argument list with type VARIABLE_ENTRY_CONSISTENCY *.
A NULL terminates the list.
@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.
@ -1543,6 +1545,8 @@ CheckRemainingSpaceForConsistency (
VARIABLE_STORE_HEADER *VariableStoreHeader;
VARIABLE_POINTER_TRACK VariablePtrTrack;
VARIABLE_HEADER *NextVariable;
UINTN VarNameSize;
UINTN VarDataSize;
//
// Non-Volatile related.
@ -1561,6 +1565,15 @@ CheckRemainingSpaceForConsistency (
VA_START (Args, Attributes);
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
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;
VariableEntry = VA_ARG (Args, VARIABLE_ENTRY_CONSISTENCY *);
}
@ -1657,8 +1670,6 @@ AutoUpdateLangVariable (
UINT32 Attributes;
VARIABLE_POINTER_TRACK Variable;
BOOLEAN SetLanguageCodes;
UINTN VarNameSize;
UINTN VarDataSize;
VARIABLE_ENTRY_CONSISTENCY VariableEntry[2];
//
@ -1782,21 +1793,13 @@ AutoUpdateLangVariable (
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);
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].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for PlatformLang variable.
//
VarNameSize = StrSize (EFI_PLATFORM_LANG_VARIABLE_NAME);
VarDataSize = AsciiStrSize (BestPlatformLang);
VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
VariableEntry[1].VariableSize = AsciiStrSize (BestPlatformLang);
VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {
@ -1839,21 +1842,13 @@ AutoUpdateLangVariable (
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);
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].VariableSize = AsciiStrSize (BestPlatformLang);
VariableEntry[0].Guid = &gEfiGlobalVariableGuid;
VariableEntry[0].Name = EFI_PLATFORM_LANG_VARIABLE_NAME;
//
// Calculate the needed variable size for Lang variable.
//
VarNameSize = StrSize (EFI_LANG_VARIABLE_NAME);
VarDataSize = ISO_639_2_ENTRY_SIZE + 1;
VariableEntry[1].VariableSize = sizeof (VARIABLE_HEADER) + VarNameSize + GET_PAD_SIZE (VarNameSize) + VarDataSize + GET_PAD_SIZE (VarDataSize);
VariableEntry[1].VariableSize = HEADER_ALIGN (VariableEntry[1].VariableSize);
VariableEntry[1].VariableSize = ISO_639_2_ENTRY_SIZE + 1;
VariableEntry[1].Guid = &gEfiGlobalVariableGuid;
VariableEntry[1].Name = EFI_LANG_VARIABLE_NAME;
if (!CheckRemainingSpaceForConsistency (VARIABLE_ATTRIBUTE_NV_BS_RT, &VariableEntry[0], &VariableEntry[1], NULL)) {

View File

@ -111,10 +111,6 @@ typedef struct {
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
// UINT32 Attributes;
//
// Variable size include variable header, name and data.
//
UINTN VariableSize;
} VARIABLE_ENTRY_CONSISTENCY;
@ -221,6 +217,32 @@ DataSizeOfVariable (
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,
index of associated public key is needed.