From 6675a21f141ce144a9e7ff39128b2a625eab80c9 Mon Sep 17 00:00:00 2001 From: Star Zeng Date: Mon, 19 Aug 2013 05:16:45 +0000 Subject: MdePkg/MdeModulePkg/SecurityPkg Variable: Forbid creation of non-spec variables in EFI_GLOBAL_VARIABLE namespace. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14560 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/Variable/RuntimeDxe/Variable.c | 131 +++++++++++++++++++-- .../Universal/Variable/RuntimeDxe/Variable.h | 9 +- 2 files changed, 127 insertions(+), 13 deletions(-) (limited to 'MdeModulePkg') diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c index d31fe0c871..51dd0fd6f7 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c @@ -44,6 +44,51 @@ BOOLEAN mEndOfDxe = FALSE; /// BOOLEAN mEnableLocking = TRUE; +// +// To prevent name collisions with possible future globally defined variables, +// other internal firmware data variables that are not defined here must be +// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or +// any other GUID defined by the UEFI Specification. Implementations must +// only permit the creation of variables with a UEFI Specification-defined +// VendorGuid when these variables are documented in the UEFI Specification. +// +GLOBAL_VARIABLE_ENTRY mGlobalVariableList[] = { + {EFI_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_TIME_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_PLATFORM_LANG_CODES_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_PLATFORM_LANG_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_CON_IN_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_CON_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_ERR_OUT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_CON_IN_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_CON_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_ERR_OUT_DEV_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_BOOT_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_BOOT_NEXT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_BOOT_CURRENT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_DRIVER_ORDER_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_SETUP_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_KEY_EXCHANGE_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT}, + {EFI_PLATFORM_KEY_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT_AT}, + {EFI_SIGNATURE_SUPPORT_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_SECURE_BOOT_MODE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_KEK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_PK_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_DB_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_DBX_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_DBT_DEFAULT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, + {EFI_OS_INDICATIONS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_NV_BS_RT}, + {EFI_VENDOR_KEYS_VARIABLE_NAME, VARIABLE_ATTRIBUTE_BS_RT}, +}; +GLOBAL_VARIABLE_ENTRY mGlobalVariableList2[] = { + {L"Boot####", VARIABLE_ATTRIBUTE_NV_BS_RT}, + {L"Driver####", VARIABLE_ATTRIBUTE_NV_BS_RT}, + {L"Key####", VARIABLE_ATTRIBUTE_NV_BS_RT}, +}; /** Routine used to track statistical information about variable usage. @@ -1236,7 +1281,7 @@ AutoUpdateLangVariable ( SetLanguageCodes = FALSE; - if (StrCmp (VariableName, L"PlatformLangCodes") == 0) { + if (StrCmp (VariableName, EFI_PLATFORM_LANG_CODES_VARIABLE_NAME) == 0) { // // PlatformLangCodes is a volatile variable, so it can not be updated at runtime. // @@ -1266,7 +1311,7 @@ AutoUpdateLangVariable ( mVariableModuleGlobal->PlatformLang = AllocateRuntimePool (DataSize); ASSERT (mVariableModuleGlobal->PlatformLang != NULL); - } else if (StrCmp (VariableName, L"LangCodes") == 0) { + } else if (StrCmp (VariableName, EFI_LANG_CODES_VARIABLE_NAME) == 0) { // // LangCodes is a volatile variable, so it can not be updated at runtime. // @@ -1294,21 +1339,21 @@ AutoUpdateLangVariable ( // Update Lang if PlatformLang is already set // Update PlatformLang if Lang is already set // - Status = FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); + Status = FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); if (!EFI_ERROR (Status)) { // // Update Lang // - VariableName = L"PlatformLang"; + VariableName = EFI_PLATFORM_LANG_VARIABLE_NAME; Data = GetVariableDataPtr (Variable.CurrPtr); DataSize = Variable.CurrPtr->DataSize; } else { - Status = FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); + Status = FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); if (!EFI_ERROR (Status)) { // // Update PlatformLang // - VariableName = L"Lang"; + VariableName = EFI_LANG_VARIABLE_NAME; Data = GetVariableDataPtr (Variable.CurrPtr); DataSize = Variable.CurrPtr->DataSize; } else { @@ -1325,7 +1370,7 @@ AutoUpdateLangVariable ( // Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; - if (StrCmp (VariableName, L"PlatformLang") == 0) { + if (StrCmp (VariableName, EFI_PLATFORM_LANG_VARIABLE_NAME) == 0) { // // Update Lang when PlatformLangCodes/LangCodes were set. // @@ -1348,9 +1393,9 @@ AutoUpdateLangVariable ( // // Successfully convert PlatformLang to Lang, and set the BestLang value into Lang variable simultaneously. // - FindVariable (L"Lang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); + FindVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); - Status = UpdateVariable (L"Lang", &gEfiGlobalVariableGuid, BestLang, + Status = UpdateVariable (EFI_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestLang, ISO_639_2_ENTRY_SIZE + 1, Attributes, &Variable); DEBUG ((EFI_D_INFO, "Variable Driver Auto Update PlatformLang, PlatformLang:%a, Lang:%a\n", BestPlatformLang, BestLang)); @@ -1359,7 +1404,7 @@ AutoUpdateLangVariable ( } } - } else if (StrCmp (VariableName, L"Lang") == 0) { + } else if (StrCmp (VariableName, EFI_LANG_VARIABLE_NAME) == 0) { // // Update PlatformLang when PlatformLangCodes/LangCodes were set. // @@ -1382,9 +1427,9 @@ AutoUpdateLangVariable ( // // Successfully convert Lang to PlatformLang, and set the BestPlatformLang value into PlatformLang variable simultaneously. // - FindVariable (L"PlatformLang", &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); + FindVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE); - Status = UpdateVariable (L"PlatformLang", &gEfiGlobalVariableGuid, BestPlatformLang, + Status = UpdateVariable (EFI_PLATFORM_LANG_VARIABLE_NAME, &gEfiGlobalVariableGuid, BestPlatformLang, AsciiStrSize (BestPlatformLang), Attributes, &Variable); DEBUG ((EFI_D_INFO, "Variable Driver Auto Update Lang, Lang:%a, PlatformLang:%a\n", BestLang, BestPlatformLang)); @@ -1934,6 +1979,63 @@ IsHwErrRecVariable ( return TRUE; } +/** + This code checks if variable guid is global variable guid first. + If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2 and attributes matched. + + @param[in] VariableName Pointer to variable name. + @param[in] VendorGuid Variable Vendor Guid. + @param[in] Attributes Attributes of the variable. + + @retval EFI_SUCCESS Variable is not global variable, or Variable is global variable, variable name is in the lists and attributes matched. + @retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists or attributes unmatched. + +**/ +EFI_STATUS +EFIAPI +CheckEfiGlobalVariable ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes + ) +{ + UINTN Index; + UINTN NameLength; + + if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid)){ + // + // Try list 1, exactly match. + // + for (Index = 0; Index < sizeof (mGlobalVariableList)/sizeof (mGlobalVariableList[0]); Index++) { + if ((StrCmp (mGlobalVariableList[Index].Name, VariableName) == 0) && + (Attributes == 0 || Attributes == mGlobalVariableList[Index].Attributes)) { + return EFI_SUCCESS; + } + } + + // + // Try list 2. + // + NameLength = StrLen (VariableName) - 4; + for (Index = 0; Index < sizeof (mGlobalVariableList2)/sizeof (mGlobalVariableList2[0]); Index++) { + if ((StrLen (VariableName) == StrLen (mGlobalVariableList2[Index].Name)) && + (StrnCmp (mGlobalVariableList2[Index].Name, VariableName, NameLength) == 0) && + IsHexaDecimalDigitCharacter (VariableName[NameLength]) && + IsHexaDecimalDigitCharacter (VariableName[NameLength + 1]) && + IsHexaDecimalDigitCharacter (VariableName[NameLength + 2]) && + IsHexaDecimalDigitCharacter (VariableName[NameLength + 3]) && + (Attributes == 0 || Attributes == mGlobalVariableList2[Index].Attributes)) { + return EFI_SUCCESS; + } + } + + DEBUG ((EFI_D_INFO, "[Variable]: set global variable with invalid variable name or attributes - %g:%s:%x\n", VendorGuid, VariableName, Attributes)); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + /** Mark a variable that will become read-only after leaving the DXE phase of execution. @@ -2317,6 +2419,11 @@ VariableServiceSetVariable ( } } + Status = CheckEfiGlobalVariable (VariableName, VendorGuid, Attributes); + if (EFI_ERROR (Status)) { + return Status; + } + AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock); // diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h index 264a2396c6..a10ad8755a 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h @@ -42,7 +42,14 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include -#define VARIABLE_RECLAIM_THRESHOLD (1024) +#define VARIABLE_ATTRIBUTE_BS_RT (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS) +#define VARIABLE_ATTRIBUTE_NV_BS_RT (VARIABLE_ATTRIBUTE_BS_RT | EFI_VARIABLE_NON_VOLATILE) +#define VARIABLE_ATTRIBUTE_NV_BS_RT_AT (VARIABLE_ATTRIBUTE_NV_BS_RT | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) + +typedef struct { + CHAR16 *Name; + UINT32 Attributes; +} GLOBAL_VARIABLE_ENTRY; /// /// The size of a 3 character ISO639 language code. -- cgit v1.2.3