From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: hao.a.wu@intel.com) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by groups.io with SMTP; Fri, 27 Sep 2019 01:17:46 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Sep 2019 01:17:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,554,1559545200"; d="scan'208";a="196642637" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by FMSMGA003.fm.intel.com with ESMTP; 27 Sep 2019 01:17:45 -0700 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 27 Sep 2019 01:17:45 -0700 Received: from shsmsx105.ccr.corp.intel.com (10.239.4.158) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.439.0; Fri, 27 Sep 2019 01:17:45 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.32]) by SHSMSX105.ccr.corp.intel.com ([169.254.11.23]) with mapi id 14.03.0439.000; Fri, 27 Sep 2019 16:17:42 +0800 From: "Wu, Hao A" To: "devel@edk2.groups.io" , "Kubacki, Michael A" CC: "Bi, Dandan" , Ard Biesheuvel , "Dong, Eric" , Laszlo Ersek , "Gao, Liming" , "Kinney, Michael D" , "Ni, Ray" , "Wang, Jian J" , "Yao, Jiewen" Subject: Re: [edk2-devel] [PATCH V1 1/5] MdeModulePkg/Variable: Consolidate common parsing functions Thread-Topic: [edk2-devel] [PATCH V1 1/5] MdeModulePkg/Variable: Consolidate common parsing functions Thread-Index: AQHVdCYVg+5ON2UD9U+GYYppL2t5+Kc/J+7A Date: Fri, 27 Sep 2019 08:17:42 +0000 Message-ID: References: <20190926045046.34592-1-michael.a.kubacki@intel.com> <20190926045046.34592-2-michael.a.kubacki@intel.com> In-Reply-To: <20190926045046.34592-2-michael.a.kubacki@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: hao.a.wu@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable > -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of > Kubacki, Michael A > Sent: Thursday, September 26, 2019 12:51 PM > To: devel@edk2.groups.io > Cc: Bi, Dandan; Ard Biesheuvel; Dong, Eric; Laszlo Ersek; Gao, Liming; K= inney, > Michael D; Ni, Ray; Wang, Jian J; Wu, Hao A; Yao, Jiewen > Subject: [edk2-devel] [PATCH V1 1/5] MdeModulePkg/Variable: Consolidate > common parsing functions >=20 > This change moves the following functions into a dedicated file > so they may be used in other variable files as needed. Furthermore, > it reduces the overall size of the common Variable.c file. >=20 > * DataSizeOfVariable () > * FindVariableEx () > * GetEndPointer () > * GetNextVariableEx () > * GetNextVariablePtr () > * GetStartPointer () > * GetVariableDataOffset () > * GetVariableDataPtr () > * GetVariableHeaderSize () > * GetVariableNamePtr () > * GetVariableStoreStatus () > * GetVendorGuidPtr () > * IsAuthenticatedVariable () > * IsValidVariableHeader () > * NameSizeOfVariable () > * SetDataSizeOfVariable () > * SetNameSizeOfVariable () > * UpdateVariableInfo () > * VariableCompareTimeStampInternal () Hello, Some thoughts for this patch: (Sorry for not being able to going through the whole series, and please gr= ant more time for the review of other patches.) 0. I would suggest this patch only changing the location for functions. Modifications that might have functional impact need be separated to other independent patches. 1. For UpdateVariableInfo(), I think it is still possible for file VariableParsing.c to reference 'gVariableInfo'. The additional input param= eter can be drop, in my opinion. 2. It would be better for the removal of VariableServiceGetNextVariableInt= ernal() to be a separate patch. 3. Maybe the introduce of InitVariableHelpers() can be separated to anothe= r patch. Also, I think variable 'mVariableModuleGlobal' can be referred in file VariableParsing.c. Is the intention of adding InitVariableHelpers() to reduce code length from: if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { to: if (mAuthFormat) { 4. I am confused for the changes made in: MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.c MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf Originally, for VariableSmmRuntimeDxe.inf, the source code file includes: [Sources] VariableSmmRuntimeDxe.c PrivilegePolymorphic.h Measurement.c The proposed patch only adds the below header inclusion: #include "VariableParsing.h" to file VariableSmmRuntimeDxe.c, which has no functional impact in my opin= ion. Could you help to check whether changes made for VariableSmmRuntimeDxe is = needed? Best Regards, Hao Wu >=20 > Cc: Dandan Bi > Cc: Ard Biesheuvel > Cc: Eric Dong > Cc: Laszlo Ersek > Cc: Liming Gao > Cc: Michael D Kinney > Cc: Ray Ni > Cc: Jian J Wang > Cc: Hao A Wu > Cc: Jiewen Yao > Signed-off-by: Michael Kubacki > --- > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > | 4 + > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf | = 4 > + >=20 > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.i > nf | 8 +- >=20 > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf > | 9 + > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h | = 119 --- > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h | > 25 + > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h | > 342 ++++++++ > MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c | = 784 +-- > ---------------- > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c | = 11 > +- > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c | > 28 + > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c | > 816 ++++++++++++++++++++ > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c | = 2 > + >=20 > MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe. > c | 3 +- > 13 files changed, 1273 insertions(+), 882 deletions(-) >=20 > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > index 641376c9c5..08a5490787 100644 > --- > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf > @@ -36,6 +36,10 @@ > Variable.c > VariableDxe.c > Variable.h > + VariableNonVolatile.c > + VariableNonVolatile.h > + VariableParsing.c > + VariableParsing.h > PrivilegePolymorphic.h > Measurement.c > TcgMorLockDxe.c > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > index 0a160d269d..6dc2721b81 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf > @@ -45,6 +45,10 @@ > Variable.c > VariableTraditionalMm.c > VariableSmm.c > + VariableNonVolatile.c > + VariableNonVolatile.h > + VariableParsing.c > + VariableParsing.h > VarCheck.c > Variable.h > PrivilegePolymorphic.h > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > index 14894e6f13..1873b4fe43 100644 > --- > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.inf > @@ -13,7 +13,7 @@ > # may not be modified without authorization. If platform fails to prot= ect > these resources, > # the authentication service provided in this driver will be broken, a= nd the > behavior is undefined. > # > -# Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved. > +# Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved. > # SPDX-License-Identifier: BSD-2-Clause-Patent > # > ## > @@ -39,6 +39,9 @@ > VariableSmmRuntimeDxe.c > PrivilegePolymorphic.h > Measurement.c > + Variable.h > + VariableParsing.c > + VariableParsing.h >=20 > [Packages] > MdePkg/MdePkg.dec > @@ -65,6 +68,9 @@ > gEdkiiVariableLockProtocolGuid ## PRODUCES > gEdkiiVarCheckProtocolGuid ## PRODUCES >=20 > +[FeaturePcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics = ## > CONSUMES > + > [Guids] > gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event > gEfiEventExitBootServicesGuid ## CONSUMES ## Event > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i > nf > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm. > inf > index 21bc81163b..ca9d23ce9f 100644 > --- > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.i > nf > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm. > inf > @@ -45,6 +45,10 @@ > Variable.c > VariableSmm.c > VariableStandaloneMm.c > + VariableNonVolatile.c > + VariableNonVolatile.h > + VariableParsing.c > + VariableParsing.h > VarCheck.c > Variable.h > PrivilegePolymorphic.h > @@ -99,6 +103,11 @@ > ## SOMETIMES_PRODUCES ## Variable:L"Lang" > gEfiGlobalVariableGuid >=20 > + ## SOMETIMES_CONSUMES ## Variable:L"db" > + ## SOMETIMES_CONSUMES ## Variable:L"dbx" > + ## SOMETIMES_CONSUMES ## Variable:L"dbt" > + gEfiImageSecurityDatabaseGuid > + > gEfiMemoryOverwriteControlDataGuid ## SOMETIMES_CONSUMES > ## Variable:L"MemoryOverwriteRequestControl" > gEfiMemoryOverwriteRequestControlLockGuid ## > SOMETIMES_PRODUCES ## > Variable:L"MemoryOverwriteRequestControlLock" >=20 > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > index 9eac43759f..fb574b2e32 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.h > @@ -179,89 +179,6 @@ FindVariable ( > IN BOOLEAN IgnoreRtCheck > ); >=20 > -/** > - > - Gets the pointer to the end of the variable storage area. > - > - This function gets pointer to the end of the variable storage > - area, according to the input variable store header. > - > - @param VarStoreHeader Pointer to the Variable Store Header. > - > - @return Pointer to the end of the variable storage area. > - > -**/ > -VARIABLE_HEADER * > -GetEndPointer ( > - IN VARIABLE_STORE_HEADER *VarStoreHeader > - ); > - > -/** > - This code gets the size of variable header. > - > - @return Size of variable header in bytes in type UINTN. > - > -**/ > -UINTN > -GetVariableHeaderSize ( > - VOID > - ); > - > -/** > - > - This code gets the pointer to the variable name. > - > - @param Variable Pointer to the Variable Header. > - > - @return Pointer to Variable Name which is Unicode encoding. > - > -**/ > -CHAR16 * > -GetVariableNamePtr ( > - IN VARIABLE_HEADER *Variable > - ); > - > -/** > - This code gets the pointer to the variable guid. > - > - @param Variable Pointer to the Variable Header. > - > - @return A EFI_GUID* pointer to Vendor Guid. > - > -**/ > -EFI_GUID * > -GetVendorGuidPtr ( > - IN VARIABLE_HEADER *Variable > - ); > - > -/** > - > - This code gets the pointer to the variable data. > - > - @param Variable Pointer to the Variable Header. > - > - @return Pointer to Variable Data. > - > -**/ > -UINT8 * > -GetVariableDataPtr ( > - IN VARIABLE_HEADER *Variable > - ); > - > -/** > - > - This code gets the size of variable data. > - > - @param Variable Pointer to the Variable Header. > - > - @return Size of variable in bytes. > - > -**/ > -UINTN > -DataSizeOfVariable ( > - IN VARIABLE_HEADER *Variable > - ); > - > /** > This function is to check if the remaining variable space is enough t= o set > all Variables from argument list successfully. The purpose of the che= ck > @@ -450,17 +367,6 @@ ReclaimForOS( > VOID > ); >=20 > -/** > - Get non-volatile maximum variable size. > - > - @return Non-volatile maximum variable size. > - > -**/ > -UINTN > -GetNonVolatileMaxVariableSize ( > - VOID > - ); > - > /** > Get maximum variable size, covering both non-volatile and volatile va= riables. >=20 > @@ -546,31 +452,6 @@ VariableServiceGetVariable ( > OUT VOID *Data OPTIONAL > ); >=20 > -/** > - This code Finds the Next available variable. > - > - Caution: This function may receive untrusted input. > - This function may be invoked in SMM mode. This function will do basic > validation, before parse the data. > - > - @param[in] VariableName Pointer to variable name. > - @param[in] VendorGuid Variable Vendor Guid. > - @param[out] VariablePtr Pointer to variable header address. > - > - @retval EFI_SUCCESS The function completed successfully. > - @retval EFI_NOT_FOUND The next variable was not found. > - @retval EFI_INVALID_PARAMETER If VariableName is not an empty string, > while VendorGuid is NULL. > - @retval EFI_INVALID_PARAMETER The input values of VariableName and > VendorGuid are not a name and > - GUID of an existing variable. > - > -**/ > -EFI_STATUS > -EFIAPI > -VariableServiceGetNextVariableInternal ( > - IN CHAR16 *VariableName, > - IN EFI_GUID *VendorGuid, > - OUT VARIABLE_HEADER **VariablePtr > - ); > - > /** >=20 > This code Finds the Next available variable. > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h > new file mode 100644 > index 0000000000..82572262ef > --- /dev/null > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.h > @@ -0,0 +1,25 @@ > +/** @file > + Common variable non-volatile store routines. > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _VARIABLE_NON_VOLATILE_H_ > +#define _VARIABLE_NON_VOLATILE_H_ > + > +#include "Variable.h" > + > +/** > + Get non-volatile maximum variable size. > + > + @return Non-volatile maximum variable size. > + > +**/ > +UINTN > +GetNonVolatileMaxVariableSize ( > + VOID > + ); > + > +#endif > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h > new file mode 100644 > index 0000000000..bd617fca10 > --- /dev/null > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.h > @@ -0,0 +1,342 @@ > +/** @file > + Common variable helper routines are shared by the DXE_RUNTIME > variable > + module and the DXE_SMM variable module. > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _VARIABLE_PARSING_H_ > +#define _VARIABLE_PARSING_H_ > + > +#include > +#include "Variable.h" > + > +/** > + > + This code checks if variable header is valid or not. > + > + @param Variable Pointer to the Variable Header. > + @param VariableStoreEnd Pointer to the Variable Store End. > + > + @retval TRUE Variable header is valid. > + @retval FALSE Variable header is not valid. > + > +**/ > +BOOLEAN > +IsValidVariableHeader ( > + IN VARIABLE_HEADER *Variable, > + IN VARIABLE_HEADER *VariableStoreEnd > + ); > + > +/** > + > + This code gets the current status of Variable Store. > + > + @param VarStoreHeader Pointer to the Variable Store Header. > + > + @retval EfiRaw Variable store status is raw. > + @retval EfiValid Variable store status is valid. > + @retval EfiInvalid Variable store status is invalid. > + > +**/ > +VARIABLE_STORE_STATUS > +GetVariableStoreStatus ( > + IN VARIABLE_STORE_HEADER *VarStoreHeader > + ); > + > +/** > + This code gets the size of variable header. > + > + @return Size of variable header in bytes in type UINTN. > + > +**/ > +UINTN > +GetVariableHeaderSize ( > + VOID > + ); > + > +/** > + > + This code gets the size of name of variable. > + > + @param Variable Pointer to the Variable Header. > + > + @return UINTN Size of variable in bytes. > + > +**/ > +UINTN > +NameSizeOfVariable ( > + IN VARIABLE_HEADER *Variable > + ); > + > +/** > + This code sets the size of name of variable. > + > + @param[in] Variable Pointer to the Variable Header. > + @param[in] NameSize Name size to set. > + > +**/ > +VOID > +SetNameSizeOfVariable ( > + IN VARIABLE_HEADER *Variable, > + IN UINTN NameSize > + ); > + > +/** > + > + This code gets the size of variable data. > + > + @param Variable Pointer to the Variable Header. > + > + @return Size of variable in bytes. > + > +**/ > +UINTN > +DataSizeOfVariable ( > + IN VARIABLE_HEADER *Variable > + ); > + > +/** > + This code sets the size of variable data. > + > + @param[in] Variable Pointer to the Variable Header. > + @param[in] DataSize Data size to set. > + > +**/ > +VOID > +SetDataSizeOfVariable ( > + IN VARIABLE_HEADER *Variable, > + IN UINTN DataSize > + ); > + > +/** > + > + This code gets the pointer to the variable name. > + > + @param Variable Pointer to the Variable Header. > + > + @return Pointer to Variable Name which is Unicode encoding. > + > +**/ > +CHAR16 * > +GetVariableNamePtr ( > + IN VARIABLE_HEADER *Variable > + ); > + > +/** > + This code gets the pointer to the variable guid. > + > + @param Variable Pointer to the Variable Header. > + > + @return A EFI_GUID* pointer to Vendor Guid. > + > +**/ > +EFI_GUID * > +GetVendorGuidPtr ( > + IN VARIABLE_HEADER *Variable > + ); > + > +/** > + > + This code gets the pointer to the variable data. > + > + @param Variable Pointer to the Variable Header. > + > + @return Pointer to Variable Data. > + > +**/ > +UINT8 * > +GetVariableDataPtr ( > + IN VARIABLE_HEADER *Variable > + ); > + > +/** > + This code gets the variable data offset related to variable header. > + > + @param Variable Pointer to the Variable Header. > + > + @return Variable Data offset. > + > +**/ > +UINTN > +GetVariableDataOffset ( > + IN VARIABLE_HEADER *Variable > + ); > + > +/** > + > + This code gets the pointer to the next variable header. > + > + @param Variable Pointer to the Variable Header. > + > + @return Pointer to next variable header. > + > +**/ > +VARIABLE_HEADER * > +GetNextVariablePtr ( > + IN VARIABLE_HEADER *Variable > + ); > + > +/** > + > + Gets the pointer to the first variable header in given variable store= area. > + > + @param VarStoreHeader Pointer to the Variable Store Header. > + > + @return Pointer to the first variable header. > + > +**/ > +VARIABLE_HEADER * > +GetStartPointer ( > + IN VARIABLE_STORE_HEADER *VarStoreHeader > + ); > + > +/** > + > + Gets the pointer to the end of the variable storage area. > + > + This function gets pointer to the end of the variable storage > + area, according to the input variable store header. > + > + @param VarStoreHeader Pointer to the Variable Store Header. > + > + @return Pointer to the end of the variable storage area. > + > +**/ > +VARIABLE_HEADER * > +GetEndPointer ( > + IN VARIABLE_STORE_HEADER *VarStoreHeader > + ); > + > +/** > + Returns if this is a variable that always requires authenticated writ= es. > + There may be other scenarios that result in a variable not identified= by the > + function to also require authentication. > + > + @param[in] VariableName Name of variable. > + @param[in] VendorGuid Guid of variable. > + > + @retval TRUE The variable always requires authenticated w= rites > + @retval FALSE The variable may or may not require authenti= cated > writes > +**/ > +BOOLEAN > +IsAuthenticatedVariable ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid > + ); > + > +/** > + Compare two EFI_TIME data. > + > + > + @param FirstTime A pointer to the first EFI_TIME data. > + @param SecondTime A pointer to the second EFI_TIME data. > + > + @retval TRUE The FirstTime is not later than the Second= Time. > + @retval FALSE The FirstTime is later than the SecondTime= . > + > +**/ > +BOOLEAN > +VariableCompareTimeStampInternal ( > + IN EFI_TIME *FirstTime, > + IN EFI_TIME *SecondTime > + ); > + > +/** > + Find the variable in the specified variable store. > + > + @param[in] VariableName Name of the variable to be found > + @param[in] VendorGuid Vendor GUID to be found. > + @param[in] IgnoreRtCheck Ignore EFI_VARIABLE_RUNTIME_ACCE= SS > attribute > + check at runtime when searching = variable. > + @param[in, out] PtrTrack Variable Track Pointer structure= that > contains Variable Information. > + > + @retval EFI_SUCCESS Variable found successfully > + @retval EFI_NOT_FOUND Variable not found > +**/ > +EFI_STATUS > +FindVariableEx ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + IN BOOLEAN IgnoreRtCheck, > + IN OUT VARIABLE_POINTER_TRACK *PtrTrack > + ); > + > +/** > + This code finds the next available variable. > + > + Caution: This function may receive untrusted input. > + This function may be invoked in SMM mode. This function will do basic > validation, before parse the data. > + > + @param[in] VariableName Pointer to variable name. > + @param[in] VendorGuid Variable Vendor Guid. > + @param[in] VariableStoreList A list of variable stores that should b= e used > to get the next variable. > + The maximum number of entries is the ma= x value of > VARIABLE_STORE_TYPE. > + @param[out] VariablePtr Pointer to variable header address. > + > + @retval EFI_SUCCESS The function completed successfully. > + @retval EFI_NOT_FOUND The next variable was not found. > + @retval EFI_INVALID_PARAMETER If VariableName is nt an empty string, > while VendorGuid is NULL. > + @retval EFI_INVALID_PARAMETER The input values of VariableName and > VendorGuid are not a name and > + GUID of an existing variable. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetNextVariableEx ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + IN VARIABLE_STORE_HEADER **VariableStoreList, > + OUT VARIABLE_HEADER **VariablePtr > + ); > + > +/** > + Routine used to track statistical information about variable usage. > + The data is stored in the EFI system table so it can be accessed late= r. > + VariableInfo.efi can dump out the table. Only Boot Services variable > + accesses are tracked by this code. The PcdVariableCollectStatistics > + build flag controls if this feature is enabled. > + > + A read that hits in the cache will have Read and Cache true for > + the transaction. Data is allocated by this routine, but never > + freed. > + > + @param[in] VariableName Name of the Variable to track. > + @param[in] VendorGuid Guid of the Variable to track. > + @param[in] Volatile TRUE if volatile FALSE if non-volatile= . > + @param[in] Read TRUE if GetVariable() was called. > + @param[in] Write TRUE if SetVariable() was called. > + @param[in] Delete TRUE if deleted via SetVariable(). > + @param[in] Cache TRUE for a cache hit. > + @param[in,out] VariableInfo Pointer to a pointer of > VARIABLE_INFO_ENTRY structures. > + > +**/ > +VOID > +UpdateVariableInfo ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + IN BOOLEAN Volatile, > + IN BOOLEAN Read, > + IN BOOLEAN Write, > + IN BOOLEAN Delete, > + IN BOOLEAN Cache, > + IN OUT VARIABLE_INFO_ENTRY **VariableInfo > + ); > + > +/** > + Initializes context needed for variable helpers. > + > + @param[in] AuthFormat If true then indicates authentic= ated > variables are supported > + > + @retval EFI_SUCCESS Initialized successfully > + @retval Others An error occurred during initial= ization > +**/ > +EFI_STATUS > +EFIAPI > +InitVariableHelpers ( > + IN BOOLEAN AuthFormat > + ); > + > +#endif > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > index f32c9c2808..d14fecc830 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c > @@ -23,6 +23,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > **/ >=20 > #include "Variable.h" > +#include "VariableNonVolatile.h" > +#include "VariableParsing.h" >=20 > VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal; >=20 > @@ -92,131 +94,6 @@ AUTH_VAR_LIB_CONTEXT_IN mAuthContextIn =3D { >=20 > AUTH_VAR_LIB_CONTEXT_OUT mAuthContextOut; >=20 > -/** > - Routine used to track statistical information about variable usage. > - The data is stored in the EFI system table so it can be accessed late= r. > - VariableInfo.efi can dump out the table. Only Boot Services variable > - accesses are tracked by this code. The PcdVariableCollectStatistics > - build flag controls if this feature is enabled. > - > - A read that hits in the cache will have Read and Cache true for > - the transaction. Data is allocated by this routine, but never > - freed. > - > - @param[in] VariableName Name of the Variable to track. > - @param[in] VendorGuid Guid of the Variable to track. > - @param[in] Volatile TRUE if volatile FALSE if non-volatile. > - @param[in] Read TRUE if GetVariable() was called. > - @param[in] Write TRUE if SetVariable() was called. > - @param[in] Delete TRUE if deleted via SetVariable(). > - @param[in] Cache TRUE for a cache hit. > - > -**/ > -VOID > -UpdateVariableInfo ( > - IN CHAR16 *VariableName, > - IN EFI_GUID *VendorGuid, > - IN BOOLEAN Volatile, > - IN BOOLEAN Read, > - IN BOOLEAN Write, > - IN BOOLEAN Delete, > - IN BOOLEAN Cache > - ) > -{ > - VARIABLE_INFO_ENTRY *Entry; > - > - if (FeaturePcdGet (PcdVariableCollectStatistics)) { > - > - if (AtRuntime ()) { > - // Don't collect statistics at runtime. > - return; > - } > - > - if (gVariableInfo =3D=3D NULL) { > - // > - // On the first call allocate a entry and place a pointer to it i= n > - // the EFI System Table. > - // > - gVariableInfo =3D AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY))= ; > - ASSERT (gVariableInfo !=3D NULL); > - > - CopyGuid (&gVariableInfo->VendorGuid, VendorGuid); > - gVariableInfo->Name =3D AllocateZeroPool (StrSize (VariableName))= ; > - ASSERT (gVariableInfo->Name !=3D NULL); > - StrCpyS (gVariableInfo->Name, StrSize(VariableName)/sizeof(CHAR16= ), > VariableName); > - gVariableInfo->Volatile =3D Volatile; > - } > - > - > - for (Entry =3D gVariableInfo; Entry !=3D NULL; Entry =3D Entry->Nex= t) { > - if (CompareGuid (VendorGuid, &Entry->VendorGuid)) { > - if (StrCmp (VariableName, Entry->Name) =3D=3D 0) { > - if (Read) { > - Entry->ReadCount++; > - } > - if (Write) { > - Entry->WriteCount++; > - } > - if (Delete) { > - Entry->DeleteCount++; > - } > - if (Cache) { > - Entry->CacheCount++; > - } > - > - return; > - } > - } > - > - if (Entry->Next =3D=3D NULL) { > - // > - // If the entry is not in the table add it. > - // Next iteration of the loop will fill in the data. > - // > - Entry->Next =3D AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY))= ; > - ASSERT (Entry->Next !=3D NULL); > - > - CopyGuid (&Entry->Next->VendorGuid, VendorGuid); > - Entry->Next->Name =3D AllocateZeroPool (StrSize (VariableName))= ; > - ASSERT (Entry->Next->Name !=3D NULL); > - StrCpyS (Entry->Next->Name, StrSize(VariableName)/sizeof(CHAR16= ), > VariableName); > - Entry->Next->Volatile =3D Volatile; > - } > - > - } > - } > -} > - > - > -/** > - > - This code checks if variable header is valid or not. > - > - @param Variable Pointer to the Variable Header. > - @param VariableStoreEnd Pointer to the Variable Store End. > - > - @retval TRUE Variable header is valid. > - @retval FALSE Variable header is not valid. > - > -**/ > -BOOLEAN > -IsValidVariableHeader ( > - IN VARIABLE_HEADER *Variable, > - IN VARIABLE_HEADER *VariableStoreEnd > - ) > -{ > - if ((Variable =3D=3D NULL) || (Variable >=3D VariableStoreEnd) || (Va= riable- > >StartId !=3D VARIABLE_DATA)) { > - // > - // Variable is NULL or has reached the end of variable store, > - // or the StartId is not correct. > - // > - return FALSE; > - } > - > - return TRUE; > -} > - > - > /** >=20 > This function writes data to the FWH at the correct LBA even if the L= BAs > @@ -376,345 +253,6 @@ UpdateVariableStore ( > return EFI_SUCCESS; > } >=20 > - > -/** > - > - This code gets the current status of Variable Store. > - > - @param VarStoreHeader Pointer to the Variable Store Header. > - > - @retval EfiRaw Variable store status is raw. > - @retval EfiValid Variable store status is valid. > - @retval EfiInvalid Variable store status is invalid. > - > -**/ > -VARIABLE_STORE_STATUS > -GetVariableStoreStatus ( > - IN VARIABLE_STORE_HEADER *VarStoreHeader > - ) > -{ > - if ((CompareGuid (&VarStoreHeader->Signature, > &gEfiAuthenticatedVariableGuid) || > - CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)) && > - VarStoreHeader->Format =3D=3D VARIABLE_STORE_FORMATTED && > - VarStoreHeader->State =3D=3D VARIABLE_STORE_HEALTHY > - ) { > - > - return EfiValid; > - } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] =3D=3D 0xfffff= fff && > - ((UINT32 *)(&VarStoreHeader->Signature))[1] =3D=3D 0xfffff= fff && > - ((UINT32 *)(&VarStoreHeader->Signature))[2] =3D=3D 0xfffff= fff && > - ((UINT32 *)(&VarStoreHeader->Signature))[3] =3D=3D 0xfffff= fff && > - VarStoreHeader->Size =3D=3D 0xffffffff && > - VarStoreHeader->Format =3D=3D 0xff && > - VarStoreHeader->State =3D=3D 0xff > - ) { > - > - return EfiRaw; > - } else { > - return EfiInvalid; > - } > -} > - > -/** > - This code gets the size of variable header. > - > - @return Size of variable header in bytes in type UINTN. > - > -**/ > -UINTN > -GetVariableHeaderSize ( > - VOID > - ) > -{ > - UINTN Value; > - > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > - Value =3D sizeof (AUTHENTICATED_VARIABLE_HEADER); > - } else { > - Value =3D sizeof (VARIABLE_HEADER); > - } > - > - return Value; > -} > - > -/** > - > - This code gets the size of name of variable. > - > - @param Variable Pointer to the Variable Header. > - > - @return UINTN Size of variable in bytes. > - > -**/ > -UINTN > -NameSizeOfVariable ( > - IN VARIABLE_HEADER *Variable > - ) > -{ > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > - > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > - if (AuthVariable->State =3D=3D (UINT8) (-1) || > - AuthVariable->DataSize =3D=3D (UINT32) (-1) || > - AuthVariable->NameSize =3D=3D (UINT32) (-1) || > - AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > - return 0; > - } > - return (UINTN) AuthVariable->NameSize; > - } else { > - if (Variable->State =3D=3D (UINT8) (-1) || > - Variable->DataSize =3D=3D (UINT32) (-1) || > - Variable->NameSize =3D=3D (UINT32) (-1) || > - Variable->Attributes =3D=3D (UINT32) (-1)) { > - return 0; > - } > - return (UINTN) Variable->NameSize; > - } > -} > - > -/** > - This code sets the size of name of variable. > - > - @param[in] Variable Pointer to the Variable Header. > - @param[in] NameSize Name size to set. > - > -**/ > -VOID > -SetNameSizeOfVariable ( > - IN VARIABLE_HEADER *Variable, > - IN UINTN NameSize > - ) > -{ > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > - > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > - AuthVariable->NameSize =3D (UINT32) NameSize; > - } else { > - Variable->NameSize =3D (UINT32) NameSize; > - } > -} > - > -/** > - > - This code gets the size of variable data. > - > - @param Variable Pointer to the Variable Header. > - > - @return Size of variable in bytes. > - > -**/ > -UINTN > -DataSizeOfVariable ( > - IN VARIABLE_HEADER *Variable > - ) > -{ > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > - > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > - if (AuthVariable->State =3D=3D (UINT8) (-1) || > - AuthVariable->DataSize =3D=3D (UINT32) (-1) || > - AuthVariable->NameSize =3D=3D (UINT32) (-1) || > - AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > - return 0; > - } > - return (UINTN) AuthVariable->DataSize; > - } else { > - if (Variable->State =3D=3D (UINT8) (-1) || > - Variable->DataSize =3D=3D (UINT32) (-1) || > - Variable->NameSize =3D=3D (UINT32) (-1) || > - Variable->Attributes =3D=3D (UINT32) (-1)) { > - return 0; > - } > - return (UINTN) Variable->DataSize; > - } > -} > - > -/** > - This code sets the size of variable data. > - > - @param[in] Variable Pointer to the Variable Header. > - @param[in] DataSize Data size to set. > - > -**/ > -VOID > -SetDataSizeOfVariable ( > - IN VARIABLE_HEADER *Variable, > - IN UINTN DataSize > - ) > -{ > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > - > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > - AuthVariable->DataSize =3D (UINT32) DataSize; > - } else { > - Variable->DataSize =3D (UINT32) DataSize; > - } > -} > - > -/** > - > - This code gets the pointer to the variable name. > - > - @param Variable Pointer to the Variable Header. > - > - @return Pointer to Variable Name which is Unicode encoding. > - > -**/ > -CHAR16 * > -GetVariableNamePtr ( > - IN VARIABLE_HEADER *Variable > - ) > -{ > - return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize ()); > -} > - > -/** > - This code gets the pointer to the variable guid. > - > - @param Variable Pointer to the Variable Header. > - > - @return A EFI_GUID* pointer to Vendor Guid. > - > -**/ > -EFI_GUID * > -GetVendorGuidPtr ( > - IN VARIABLE_HEADER *Variable > - ) > -{ > - AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > - > - AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > - if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > - return &AuthVariable->VendorGuid; > - } else { > - return &Variable->VendorGuid; > - } > -} > - > -/** > - > - This code gets the pointer to the variable data. > - > - @param Variable Pointer to the Variable Header. > - > - @return Pointer to Variable Data. > - > -**/ > -UINT8 * > -GetVariableDataPtr ( > - IN VARIABLE_HEADER *Variable > - ) > -{ > - UINTN Value; > - > - // > - // Be careful about pad size for alignment. > - // > - Value =3D (UINTN) GetVariableNamePtr (Variable); > - Value +=3D NameSizeOfVariable (Variable); > - Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > - > - return (UINT8 *) Value; > -} > - > -/** > - This code gets the variable data offset related to variable header. > - > - @param Variable Pointer to the Variable Header. > - > - @return Variable Data offset. > - > -**/ > -UINTN > -GetVariableDataOffset ( > - IN VARIABLE_HEADER *Variable > - ) > -{ > - UINTN Value; > - > - // > - // Be careful about pad size for alignment > - // > - Value =3D GetVariableHeaderSize (); > - Value +=3D NameSizeOfVariable (Variable); > - Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > - > - return Value; > -} > - > -/** > - > - This code gets the pointer to the next variable header. > - > - @param Variable Pointer to the Variable Header. > - > - @return Pointer to next variable header. > - > -**/ > -VARIABLE_HEADER * > -GetNextVariablePtr ( > - IN VARIABLE_HEADER *Variable > - ) > -{ > - UINTN Value; > - > - Value =3D (UINTN) GetVariableDataPtr (Variable); > - Value +=3D DataSizeOfVariable (Variable); > - Value +=3D GET_PAD_SIZE (DataSizeOfVariable (Variable)); > - > - // > - // Be careful about pad size for alignment. > - // > - return (VARIABLE_HEADER *) HEADER_ALIGN (Value); > -} > - > -/** > - > - Gets the pointer to the first variable header in given variable store= area. > - > - @param VarStoreHeader Pointer to the Variable Store Header. > - > - @return Pointer to the first variable header. > - > -**/ > -VARIABLE_HEADER * > -GetStartPointer ( > - IN VARIABLE_STORE_HEADER *VarStoreHeader > - ) > -{ > - // > - // The start of variable store. > - // > - return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1); > -} > - > -/** > - > - Gets the pointer to the end of the variable storage area. > - > - This function gets pointer to the end of the variable storage > - area, according to the input variable store header. > - > - @param VarStoreHeader Pointer to the Variable Store Header. > - > - @return Pointer to the end of the variable storage area. > - > -**/ > -VARIABLE_HEADER * > -GetEndPointer ( > - IN VARIABLE_STORE_HEADER *VarStoreHeader > - ) > -{ > - // > - // The end of variable store > - // > - return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + > VarStoreHeader->Size); > -} > - > /** > Record variable error flag. >=20 > @@ -1228,75 +766,6 @@ Done: > return Status; > } >=20 > -/** > - Find the variable in the specified variable store. > - > - @param[in] VariableName Name of the variable to be found > - @param[in] VendorGuid Vendor GUID to be found. > - @param[in] IgnoreRtCheck Ignore EFI_VARIABLE_RUNTIME_ACCE= SS > attribute > - check at runtime when searching = variable. > - @param[in, out] PtrTrack Variable Track Pointer structure= that > contains Variable Information. > - > - @retval EFI_SUCCESS Variable found successfully > - @retval EFI_NOT_FOUND Variable not found > -**/ > -EFI_STATUS > -FindVariableEx ( > - IN CHAR16 *VariableName, > - IN EFI_GUID *VendorGuid, > - IN BOOLEAN IgnoreRtCheck, > - IN OUT VARIABLE_POINTER_TRACK *PtrTrack > - ) > -{ > - VARIABLE_HEADER *InDeletedVariable; > - VOID *Point; > - > - PtrTrack->InDeletedTransitionPtr =3D NULL; > - > - // > - // Find the variable by walk through HOB, volatile and non-volatile v= ariable > store. > - // > - InDeletedVariable =3D NULL; > - > - for ( PtrTrack->CurrPtr =3D PtrTrack->StartPtr > - ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr) > - ; PtrTrack->CurrPtr =3D GetNextVariablePtr (PtrTrack->CurrPtr) > - ) { > - if (PtrTrack->CurrPtr->State =3D=3D VAR_ADDED || > - PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITION & > VAR_ADDED) > - ) { > - if (IgnoreRtCheck || !AtRuntime () || ((PtrTrack->CurrPtr->Attrib= utes & > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > - if (VariableName[0] =3D=3D 0) { > - if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITIO= N & > VAR_ADDED)) { > - InDeletedVariable =3D PtrTrack->CurrPtr; > - } else { > - PtrTrack->InDeletedTransitionPtr =3D InDeletedVariable; > - return EFI_SUCCESS; > - } > - } else { > - if (CompareGuid (VendorGuid, GetVendorGuidPtr (PtrTrack->Curr= Ptr))) > { > - Point =3D (VOID *) GetVariableNamePtr (PtrTrack->CurrPtr); > - > - ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr) !=3D 0); > - if (CompareMem (VariableName, Point, NameSizeOfVariable > (PtrTrack->CurrPtr)) =3D=3D 0) { > - if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANS= ITION & > VAR_ADDED)) { > - InDeletedVariable =3D PtrTrack->CurrPtr; > - } else { > - PtrTrack->InDeletedTransitionPtr =3D InDeletedVariable; > - return EFI_SUCCESS; > - } > - } > - } > - } > - } > - } > - } > - > - PtrTrack->CurrPtr =3D InDeletedVariable; > - return (PtrTrack->CurrPtr =3D=3D NULL) ? EFI_NOT_FOUND : EFI_SUCCESS= ; > -} > - > - > /** > Finds variable in storage blocks of volatile and non-volatile storage= areas. >=20 > @@ -2078,38 +1547,6 @@ AutoUpdateLangVariable ( > } > } >=20 > -/** > - Compare two EFI_TIME data. > - > - > - @param FirstTime A pointer to the first EFI_TIME data. > - @param SecondTime A pointer to the second EFI_TIME data. > - > - @retval TRUE The FirstTime is not later than the Second= Time. > - @retval FALSE The FirstTime is later than the SecondTime= . > - > -**/ > -BOOLEAN > -VariableCompareTimeStampInternal ( > - IN EFI_TIME *FirstTime, > - IN EFI_TIME *SecondTime > - ) > -{ > - if (FirstTime->Year !=3D SecondTime->Year) { > - return (BOOLEAN) (FirstTime->Year < SecondTime->Year); > - } else if (FirstTime->Month !=3D SecondTime->Month) { > - return (BOOLEAN) (FirstTime->Month < SecondTime->Month); > - } else if (FirstTime->Day !=3D SecondTime->Day) { > - return (BOOLEAN) (FirstTime->Day < SecondTime->Day); > - } else if (FirstTime->Hour !=3D SecondTime->Hour) { > - return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour); > - } else if (FirstTime->Minute !=3D SecondTime->Minute) { > - return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute); > - } > - > - return (BOOLEAN) (FirstTime->Second <=3D SecondTime->Second); > -} > - > /** > Update the variable region with Variable information. If > EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set, > index of associated public key is needed. > @@ -2205,7 +1642,7 @@ UpdateVariable ( > // go to delete this variable in variable HOB and > // try to flush other variables from HOB to flash. > // > - UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, FAL= SE, > TRUE, FALSE); > + UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, FAL= SE, > TRUE, FALSE, &gVariableInfo); > FlushHobVariableToFlash (VariableName, VendorGuid); > return EFI_SUCCESS; > } > @@ -2322,7 +1759,7 @@ UpdateVariable ( > &State > ); > if (!EFI_ERROR (Status)) { > - UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatil= e, > FALSE, FALSE, TRUE, FALSE); > + UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatil= e, > FALSE, FALSE, TRUE, FALSE, &gVariableInfo); > if (!Variable->Volatile) { > CacheVariable->CurrPtr->State =3D State; > FlushHobVariableToFlash (VariableName, VendorGuid); > @@ -2341,7 +1778,7 @@ UpdateVariable ( > // > // Variable content unchanged and no need to update timestamp, ju= st > return. > // > - UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, > FALSE, TRUE, FALSE, FALSE); > + UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, > FALSE, TRUE, FALSE, FALSE, &gVariableInfo); > Status =3D EFI_SUCCESS; > goto Done; > } else if ((CacheVariable->CurrPtr->State =3D=3D VAR_ADDED) || > @@ -2570,7 +2007,7 @@ UpdateVariable ( > CacheVariable->CurrPtr =3D (VARIABLE_HEADER *)((UINTN) > CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable- > >StartPtr)); > CacheVariable->InDeletedTransitionPtr =3D NULL; > } > - UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRU= E, > FALSE, FALSE); > + UpdateVariableInfo (VariableName, VendorGuid, FALSE, FALSE, TRU= E, > FALSE, FALSE, &gVariableInfo); > FlushHobVariableToFlash (VariableName, VendorGuid); > } else { > if (IsCommonUserVariable && ((VarSize + mVariableModuleGlobal- > >CommonUserVariableTotalSize) > mVariableModuleGlobal- > >CommonMaxUserVariableSpace)) { > @@ -2720,7 +2157,7 @@ UpdateVariable ( > CacheVariable->CurrPtr =3D (VARIABLE_HEADER *)((UINTN) > CacheVariable->StartPtr + ((UINTN) Variable->CurrPtr - (UINTN) Variable- > >StartPtr)); > CacheVariable->InDeletedTransitionPtr =3D NULL; > } > - UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE= , > FALSE, FALSE); > + UpdateVariableInfo (VariableName, VendorGuid, TRUE, FALSE, TRUE= , > FALSE, FALSE, &gVariableInfo); > } > goto Done; > } > @@ -2791,7 +2228,7 @@ UpdateVariable ( > } >=20 > if (!EFI_ERROR (Status)) { > - UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE= , > FALSE, FALSE); > + UpdateVariableInfo (VariableName, VendorGuid, Volatile, FALSE, TRUE= , > FALSE, FALSE, &gVariableInfo); > if (!Volatile) { > FlushHobVariableToFlash (VariableName, VendorGuid); > } > @@ -2870,7 +2307,7 @@ VariableServiceGetVariable ( > } >=20 > *DataSize =3D VarDataSize; > - UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, TR= UE, > FALSE, FALSE, FALSE); > + UpdateVariableInfo (VariableName, VendorGuid, Variable.Volatile, TR= UE, > FALSE, FALSE, FALSE, &gVariableInfo); >=20 > Status =3D EFI_SUCCESS; > goto Done; > @@ -2885,166 +2322,6 @@ Done: > return Status; > } >=20 > -/** > - This code Finds the Next available variable. > - > - Caution: This function may receive untrusted input. > - This function may be invoked in SMM mode. This function will do basic > validation, before parse the data. > - > - @param[in] VariableName Pointer to variable name. > - @param[in] VendorGuid Variable Vendor Guid. > - @param[out] VariablePtr Pointer to variable header address. > - > - @retval EFI_SUCCESS The function completed successfully. > - @retval EFI_NOT_FOUND The next variable was not found. > - @retval EFI_INVALID_PARAMETER If VariableName is not an empty string, > while VendorGuid is NULL. > - @retval EFI_INVALID_PARAMETER The input values of VariableName and > VendorGuid are not a name and > - GUID of an existing variable. > - > -**/ > -EFI_STATUS > -EFIAPI > -VariableServiceGetNextVariableInternal ( > - IN CHAR16 *VariableName, > - IN EFI_GUID *VendorGuid, > - OUT VARIABLE_HEADER **VariablePtr > - ) > -{ > - VARIABLE_STORE_TYPE Type; > - VARIABLE_POINTER_TRACK Variable; > - VARIABLE_POINTER_TRACK VariableInHob; > - VARIABLE_POINTER_TRACK VariablePtrTrack; > - EFI_STATUS Status; > - VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax]; > - > - Status =3D FindVariable (VariableName, VendorGuid, &Variable, > &mVariableModuleGlobal->VariableGlobal, FALSE); > - if (Variable.CurrPtr =3D=3D NULL || EFI_ERROR (Status)) { > - // > - // For VariableName is an empty string, FindVariable() will try to = find and > return > - // the first qualified variable, and if FindVariable() returns erro= r > (EFI_NOT_FOUND) > - // as no any variable is found, still go to return the error > (EFI_NOT_FOUND). > - // > - if (VariableName[0] !=3D 0) { > - // > - // For VariableName is not an empty string, and FindVariable() re= turns > error as > - // VariableName and VendorGuid are not a name and GUID of an exis= ting > variable, > - // there is no way to get next variable, follow spec to return > EFI_INVALID_PARAMETER. > - // > - Status =3D EFI_INVALID_PARAMETER; > - } > - goto Done; > - } > - > - if (VariableName[0] !=3D 0) { > - // > - // If variable name is not NULL, get next variable. > - // > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > - } > - > - // > - // 0: Volatile, 1: HOB, 2: Non-Volatile. > - // The index and attributes mapping must be kept in this order as > FindVariable > - // makes use of this mapping to implement search algorithm. > - // > - VariableStoreHeader[VariableStoreTypeVolatile] =3D > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > >VariableGlobal.VolatileVariableBase; > - VariableStoreHeader[VariableStoreTypeHob] =3D > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > >VariableGlobal.HobVariableBase; > - VariableStoreHeader[VariableStoreTypeNv] =3D mNvVariableCache; > - > - while (TRUE) { > - // > - // Switch from Volatile to HOB, to Non-Volatile. > - // > - while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndPtr)) = { > - // > - // Find current storage index > - // > - for (Type =3D (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMa= x; > Type++) { > - if ((VariableStoreHeader[Type] !=3D NULL) && (Variable.StartPtr= =3D=3D > GetStartPointer (VariableStoreHeader[Type]))) { > - break; > - } > - } > - ASSERT (Type < VariableStoreTypeMax); > - // > - // Switch to next storage > - // > - for (Type++; Type < VariableStoreTypeMax; Type++) { > - if (VariableStoreHeader[Type] !=3D NULL) { > - break; > - } > - } > - // > - // Capture the case that > - // 1. current storage is the last one, or > - // 2. no further storage > - // > - if (Type =3D=3D VariableStoreTypeMax) { > - Status =3D EFI_NOT_FOUND; > - goto Done; > - } > - Variable.StartPtr =3D GetStartPointer (VariableStoreHeader[Type])= ; > - Variable.EndPtr =3D GetEndPointer (VariableStoreHeader[Type])= ; > - Variable.CurrPtr =3D Variable.StartPtr; > - } > - > - // > - // Variable is found > - // > - if (Variable.CurrPtr->State =3D=3D VAR_ADDED || Variable.CurrPtr->S= tate =3D=3D > (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { > - if (!AtRuntime () || ((Variable.CurrPtr->Attributes & > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > - if (Variable.CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITION & > VAR_ADDED)) { > - // > - // If it is a IN_DELETED_TRANSITION variable, > - // and there is also a same ADDED one at the same time, > - // don't return it. > - // > - VariablePtrTrack.StartPtr =3D Variable.StartPtr; > - VariablePtrTrack.EndPtr =3D Variable.EndPtr; > - Status =3D FindVariableEx ( > - GetVariableNamePtr (Variable.CurrPtr), > - GetVendorGuidPtr (Variable.CurrPtr), > - FALSE, > - &VariablePtrTrack > - ); > - if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State = =3D=3D > VAR_ADDED) { > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > - continue; > - } > - } > - > - // > - // Don't return NV variable when HOB overrides it > - // > - if ((VariableStoreHeader[VariableStoreTypeHob] !=3D NULL) && > (VariableStoreHeader[VariableStoreTypeNv] !=3D NULL) && > - (Variable.StartPtr =3D=3D GetStartPointer > (VariableStoreHeader[VariableStoreTypeNv])) > - ) { > - VariableInHob.StartPtr =3D GetStartPointer > (VariableStoreHeader[VariableStoreTypeHob]); > - VariableInHob.EndPtr =3D GetEndPointer > (VariableStoreHeader[VariableStoreTypeHob]); > - Status =3D FindVariableEx ( > - GetVariableNamePtr (Variable.CurrPtr), > - GetVendorGuidPtr (Variable.CurrPtr), > - FALSE, > - &VariableInHob > - ); > - if (!EFI_ERROR (Status)) { > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > - continue; > - } > - } > - > - *VariablePtr =3D Variable.CurrPtr; > - Status =3D EFI_SUCCESS; > - goto Done; > - } > - } > - > - Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > - } > - > -Done: > - return Status; > -} > - > /** >=20 > This code Finds the Next available variable. > @@ -3082,6 +2359,7 @@ VariableServiceGetNextVariableName ( > UINTN MaxLen; > UINTN VarNameSize; > VARIABLE_HEADER *VariablePtr; > + VARIABLE_STORE_HEADER > *VariableStoreHeader[VariableStoreTypeMax]; >=20 > if (VariableNameSize =3D=3D NULL || VariableName =3D=3D NULL || Vendo= rGuid =3D=3D > NULL) { > return EFI_INVALID_PARAMETER; > @@ -3101,7 +2379,16 @@ VariableServiceGetNextVariableName ( >=20 > AcquireLockOnlyAtBootTime(&mVariableModuleGlobal- > >VariableGlobal.VariableServicesLock); >=20 > - Status =3D VariableServiceGetNextVariableInternal (VariableName, > VendorGuid, &VariablePtr); > + // > + // 0: Volatile, 1: HOB, 2: Non-Volatile. > + // The index and attributes mapping must be kept in this order as > FindVariable > + // makes use of this mapping to implement search algorithm. > + // > + VariableStoreHeader[VariableStoreTypeVolatile] =3D > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > >VariableGlobal.VolatileVariableBase; > + VariableStoreHeader[VariableStoreTypeHob] =3D > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > >VariableGlobal.HobVariableBase; > + VariableStoreHeader[VariableStoreTypeNv] =3D mNvVariableCache; > + > + Status =3D GetNextVariableEx (VariableName, VendorGuid, > VariableStoreHeader, &VariablePtr); > if (!EFI_ERROR (Status)) { > VarNameSize =3D NameSizeOfVariable (VariablePtr); > ASSERT (VarNameSize !=3D 0); > @@ -3720,25 +3007,6 @@ ReclaimForOS( > } > } >=20 > -/** > - Get non-volatile maximum variable size. > - > - @return Non-volatile maximum variable size. > - > -**/ > -UINTN > -GetNonVolatileMaxVariableSize ( > - VOID > - ) > -{ > - if (PcdGet32 (PcdHwErrStorageSize) !=3D 0) { > - return MAX (MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 > (PcdMaxAuthVariableSize)), > - PcdGet32 (PcdMaxHardwareErrorVariableSize)); > - } else { > - return MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 > (PcdMaxAuthVariableSize)); > - } > -} > - > /** > Get maximum variable size, covering both non-volatile and volatile va= riables. >=20 > @@ -4024,7 +3292,7 @@ InitNonVolatileVariableStore ( > return Status; > } > mVariableModuleGlobal->VariableGlobal.EmuNvMode =3D TRUE; > - DEBUG ((DEBUG_INFO, "Variable driver will work at emulated non-vola= tile > variable mode!\n")); > + DEBUG ((DEBUG_INFO, "Variable driver will work in emulated non- > volatile variable mode!\n")); > } else { > Status =3D InitRealNonVolatileVariableStore (&VariableStoreBase); > if (EFI_ERROR (Status)) { > @@ -4040,6 +3308,9 @@ InitNonVolatileVariableStore ( > mVariableModuleGlobal->MaxVariableSize =3D PcdGet32 > (PcdMaxVariableSize); > mVariableModuleGlobal->MaxAuthVariableSize =3D ((PcdGet32 > (PcdMaxAuthVariableSize) !=3D 0) ? PcdGet32 (PcdMaxAuthVariableSize) : > mVariableModuleGlobal->MaxVariableSize); >=20 > + Status =3D InitVariableHelpers (mVariableModuleGlobal- > >VariableGlobal.AuthFormat); > + ASSERT_EFI_ERROR (Status); > + > // > // Parse non-volatile variable data and get last variable offset. > // > @@ -4470,18 +3741,13 @@ VariableCommonInitialize ( >=20 > // > // mVariableModuleGlobal->VariableGlobal.AuthFormat > - // has been initialized in InitNonVolatileVariableStore(). > + // is initialized in InitNonVolatileVariableStore(). > // > if (mVariableModuleGlobal->VariableGlobal.AuthFormat) { > DEBUG ((EFI_D_INFO, "Variable driver will work with auth variable > format!\n")); > - // > - // Set AuthSupport to FALSE first, VariableWriteServiceInitialize()= will > initialize it. > - // > - mVariableModuleGlobal->VariableGlobal.AuthSupport =3D FALSE; > VariableGuid =3D &gEfiAuthenticatedVariableGuid; > } else { > DEBUG ((EFI_D_INFO, "Variable driver will work without auth variabl= e > support!\n")); > - mVariableModuleGlobal->VariableGlobal.AuthSupport =3D FALSE; > VariableGuid =3D &gEfiVariableGuid; > } >=20 > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > index cb6fcebe2d..232d9ffe25 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableExLib.c > @@ -1,12 +1,13 @@ > /** @file > Provides variable driver extended services. >=20 > -Copyright (c) 2015, Intel Corporation. All rights reserved.
> +Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
> SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > **/ >=20 > #include "Variable.h" > +#include "VariableParsing.h" >=20 > /** > Finds variable in storage blocks of volatile and non-volatile storage= areas. > @@ -97,10 +98,16 @@ VariableExLibFindNextVariable ( > EFI_STATUS Status; > VARIABLE_HEADER *VariablePtr; > AUTHENTICATED_VARIABLE_HEADER *AuthVariablePtr; > + VARIABLE_STORE_HEADER > *VariableStoreHeader[VariableStoreTypeMax]; >=20 > - Status =3D VariableServiceGetNextVariableInternal ( > + VariableStoreHeader[VariableStoreTypeVolatile] =3D > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > >VariableGlobal.VolatileVariableBase; > + VariableStoreHeader[VariableStoreTypeHob] =3D > (VARIABLE_STORE_HEADER *) (UINTN) mVariableModuleGlobal- > >VariableGlobal.HobVariableBase; > + VariableStoreHeader[VariableStoreTypeNv] =3D mNvVariableCache; > + > + Status =3D GetNextVariableEx ( > VariableName, > VendorGuid, > + VariableStoreHeader, > &VariablePtr > ); > if (EFI_ERROR (Status)) { > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c > new file mode 100644 > index 0000000000..b1b6d8282f > --- /dev/null > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c > @@ -0,0 +1,28 @@ > +/** @file > + Common variable non-volatile store routines. > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "VariableNonVolatile.h" > + > +/** > + Get non-volatile maximum variable size. > + > + @return Non-volatile maximum variable size. > + > +**/ > +UINTN > +GetNonVolatileMaxVariableSize ( > + VOID > + ) > +{ > + if (PcdGet32 (PcdHwErrStorageSize) !=3D 0) { > + return MAX (MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 > (PcdMaxAuthVariableSize)), > + PcdGet32 (PcdMaxHardwareErrorVariableSize)); > + } else { > + return MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 > (PcdMaxAuthVariableSize)); > + } > +} > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c > new file mode 100644 > index 0000000000..d448e5a264 > --- /dev/null > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableParsing.c > @@ -0,0 +1,816 @@ > +/** @file > + The common variable helper routines shared by the DXE_RUNTIME > variable > + module and the DXE_SMM variable module. > + > + Caution: This module requires additional review when modified. > + This driver will have external input - variable data. They may be inp= ut in > SMM mode. > + This external input must be validated carefully to avoid security iss= ue like > + buffer overflow, integer overflow. > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "VariableParsing.h" > + > +typedef struct { > + CONST CHAR16 *VariableName; > + EFI_GUID *VendorGuid; > +} VARIABLE_TYPE; > + > +VARIABLE_TYPE mAlwaysAuthenticatedVariables[] =3D { > + {EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid}, > + {EFI_PLATFORM_KEY_NAME, &gEfiGlobalVariableGuid}, > + {EFI_KEY_EXCHANGE_KEY_NAME, &gEfiGlobalVariableGuid}, > + {EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid}, > + {EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid}, > + {EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid}, > +}; > + > +STATIC BOOLEAN mAuthFormat; > + > +/** > + > + This code checks if variable header is valid or not. > + > + @param Variable Pointer to the Variable Header. > + @param VariableStoreEnd Pointer to the Variable Store End. > + > + @retval TRUE Variable header is valid. > + @retval FALSE Variable header is not valid. > + > +**/ > +BOOLEAN > +IsValidVariableHeader ( > + IN VARIABLE_HEADER *Variable, > + IN VARIABLE_HEADER *VariableStoreEnd > + ) > +{ > + if ((Variable =3D=3D NULL) || (Variable >=3D VariableStoreEnd) || (Va= riable- > >StartId !=3D VARIABLE_DATA)) { > + // > + // Variable is NULL or has reached the end of variable store, > + // or the StartId is not correct. > + // > + return FALSE; > + } > + > + return TRUE; > +} > + > +/** > + > + This code gets the current status of Variable Store. > + > + @param VarStoreHeader Pointer to the Variable Store Header. > + > + @retval EfiRaw Variable store status is raw. > + @retval EfiValid Variable store status is valid. > + @retval EfiInvalid Variable store status is invalid. > + > +**/ > +VARIABLE_STORE_STATUS > +GetVariableStoreStatus ( > + IN VARIABLE_STORE_HEADER *VarStoreHeader > + ) > +{ > + if ((CompareGuid (&VarStoreHeader->Signature, > &gEfiAuthenticatedVariableGuid) || > + CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)) && > + VarStoreHeader->Format =3D=3D VARIABLE_STORE_FORMATTED && > + VarStoreHeader->State =3D=3D VARIABLE_STORE_HEALTHY > + ) { > + > + return EfiValid; > + } else if (((UINT32 *)(&VarStoreHeader->Signature))[0] =3D=3D 0xfffff= fff && > + ((UINT32 *)(&VarStoreHeader->Signature))[1] =3D=3D 0xfffff= fff && > + ((UINT32 *)(&VarStoreHeader->Signature))[2] =3D=3D 0xfffff= fff && > + ((UINT32 *)(&VarStoreHeader->Signature))[3] =3D=3D 0xfffff= fff && > + VarStoreHeader->Size =3D=3D 0xffffffff && > + VarStoreHeader->Format =3D=3D 0xff && > + VarStoreHeader->State =3D=3D 0xff > + ) { > + > + return EfiRaw; > + } else { > + return EfiInvalid; > + } > +} > + > +/** > + This code gets the size of variable header. > + > + @return Size of variable header in bytes in type UINTN. > + > +**/ > +UINTN > +GetVariableHeaderSize ( > + VOID > + ) > +{ > + UINTN Value; > + > + if (mAuthFormat) { > + Value =3D sizeof (AUTHENTICATED_VARIABLE_HEADER); > + } else { > + Value =3D sizeof (VARIABLE_HEADER); > + } > + > + return Value; > +} > + > +/** > + > + This code gets the size of name of variable. > + > + @param Variable Pointer to the Variable Header. > + > + @return UINTN Size of variable in bytes. > + > +**/ > +UINTN > +NameSizeOfVariable ( > + IN VARIABLE_HEADER *Variable > + ) > +{ > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > + > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > + if (mAuthFormat) { > + if (AuthVariable->State =3D=3D (UINT8) (-1) || > + AuthVariable->DataSize =3D=3D (UINT32) (-1) || > + AuthVariable->NameSize =3D=3D (UINT32) (-1) || > + AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > + return 0; > + } > + return (UINTN) AuthVariable->NameSize; > + } else { > + if (Variable->State =3D=3D (UINT8) (-1) || > + Variable->DataSize =3D=3D (UINT32) (-1) || > + Variable->NameSize =3D=3D (UINT32) (-1) || > + Variable->Attributes =3D=3D (UINT32) (-1)) { > + return 0; > + } > + return (UINTN) Variable->NameSize; > + } > +} > + > +/** > + This code sets the size of name of variable. > + > + @param[in] Variable Pointer to the Variable Header. > + @param[in] NameSize Name size to set. > + > +**/ > +VOID > +SetNameSizeOfVariable ( > + IN VARIABLE_HEADER *Variable, > + IN UINTN NameSize > + ) > +{ > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > + > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > + if (mAuthFormat) { > + AuthVariable->NameSize =3D (UINT32) NameSize; > + } else { > + Variable->NameSize =3D (UINT32) NameSize; > + } > +} > + > +/** > + > + This code gets the size of variable data. > + > + @param Variable Pointer to the Variable Header. > + > + @return Size of variable in bytes. > + > +**/ > +UINTN > +DataSizeOfVariable ( > + IN VARIABLE_HEADER *Variable > + ) > +{ > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > + > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > + if (mAuthFormat) { > + if (AuthVariable->State =3D=3D (UINT8) (-1) || > + AuthVariable->DataSize =3D=3D (UINT32) (-1) || > + AuthVariable->NameSize =3D=3D (UINT32) (-1) || > + AuthVariable->Attributes =3D=3D (UINT32) (-1)) { > + return 0; > + } > + return (UINTN) AuthVariable->DataSize; > + } else { > + if (Variable->State =3D=3D (UINT8) (-1) || > + Variable->DataSize =3D=3D (UINT32) (-1) || > + Variable->NameSize =3D=3D (UINT32) (-1) || > + Variable->Attributes =3D=3D (UINT32) (-1)) { > + return 0; > + } > + return (UINTN) Variable->DataSize; > + } > +} > + > +/** > + This code sets the size of variable data. > + > + @param[in] Variable Pointer to the Variable Header. > + @param[in] DataSize Data size to set. > + > +**/ > +VOID > +SetDataSizeOfVariable ( > + IN VARIABLE_HEADER *Variable, > + IN UINTN DataSize > + ) > +{ > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > + > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > + if (mAuthFormat) { > + AuthVariable->DataSize =3D (UINT32) DataSize; > + } else { > + Variable->DataSize =3D (UINT32) DataSize; > + } > +} > + > +/** > + > + This code gets the pointer to the variable name. > + > + @param Variable Pointer to the Variable Header. > + > + @return Pointer to Variable Name which is Unicode encoding. > + > +**/ > +CHAR16 * > +GetVariableNamePtr ( > + IN VARIABLE_HEADER *Variable > + ) > +{ > + return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize ()); > +} > + > +/** > + This code gets the pointer to the variable guid. > + > + @param Variable Pointer to the Variable Header. > + > + @return A EFI_GUID* pointer to Vendor Guid. > + > +**/ > +EFI_GUID * > +GetVendorGuidPtr ( > + IN VARIABLE_HEADER *Variable > + ) > +{ > + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; > + > + AuthVariable =3D (AUTHENTICATED_VARIABLE_HEADER *) Variable; > + if (mAuthFormat) { > + return &AuthVariable->VendorGuid; > + } else { > + return &Variable->VendorGuid; > + } > +} > + > +/** > + > + This code gets the pointer to the variable data. > + > + @param Variable Pointer to the Variable Header. > + > + @return Pointer to Variable Data. > + > +**/ > +UINT8 * > +GetVariableDataPtr ( > + IN VARIABLE_HEADER *Variable > + ) > +{ > + UINTN Value; > + > + // > + // Be careful about pad size for alignment. > + // > + Value =3D (UINTN) GetVariableNamePtr (Variable); > + Value +=3D NameSizeOfVariable (Variable); > + Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > + > + return (UINT8 *) Value; > +} > + > +/** > + This code gets the variable data offset related to variable header. > + > + @param Variable Pointer to the Variable Header. > + > + @return Variable Data offset. > + > +**/ > +UINTN > +GetVariableDataOffset ( > + IN VARIABLE_HEADER *Variable > + ) > +{ > + UINTN Value; > + > + // > + // Be careful about pad size for alignment > + // > + Value =3D GetVariableHeaderSize (); > + Value +=3D NameSizeOfVariable (Variable); > + Value +=3D GET_PAD_SIZE (NameSizeOfVariable (Variable)); > + > + return Value; > +} > + > +/** > + > + This code gets the pointer to the next variable header. > + > + @param Variable Pointer to the Variable Header. > + > + @return Pointer to next variable header. > + > +**/ > +VARIABLE_HEADER * > +GetNextVariablePtr ( > + IN VARIABLE_HEADER *Variable > + ) > +{ > + UINTN Value; > + > + Value =3D (UINTN) GetVariableDataPtr (Variable); > + Value +=3D DataSizeOfVariable (Variable); > + Value +=3D GET_PAD_SIZE (DataSizeOfVariable (Variable)); > + > + // > + // Be careful about pad size for alignment. > + // > + return (VARIABLE_HEADER *) HEADER_ALIGN (Value); > +} > + > +/** > + > + Gets the pointer to the first variable header in given variable store= area. > + > + @param VarStoreHeader Pointer to the Variable Store Header. > + > + @return Pointer to the first variable header. > + > +**/ > +VARIABLE_HEADER * > +GetStartPointer ( > + IN VARIABLE_STORE_HEADER *VarStoreHeader > + ) > +{ > + // > + // The end of variable store. > + // > + return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1); > +} > + > +/** > + > + Gets the pointer to the end of the variable storage area. > + > + This function gets pointer to the end of the variable storage > + area, according to the input variable store header. > + > + @param VarStoreHeader Pointer to the Variable Store Header. > + > + @return Pointer to the end of the variable storage area. > + > +**/ > +VARIABLE_HEADER * > +GetEndPointer ( > + IN VARIABLE_STORE_HEADER *VarStoreHeader > + ) > +{ > + // > + // The end of variable store > + // > + return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + > VarStoreHeader->Size); > +} > + > +/** > + Returns if this is a variable that always requires authenticated writ= es. > + There may be other scenarios that result in a variable not identified= by the > + function to also require authentication. > + > + @param[in] VariableName Name of variable. > + @param[in] VendorGuid Guid of variable. > + > + @retval TRUE The variable always requires authenticated w= rites > + @retval FALSE The variable may or may not require authenti= cated > writes > +**/ > +BOOLEAN > +IsAuthenticatedVariable ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid > + ) > +{ > + UINTN Index; > + > + for (Index =3D 0; Index < sizeof (mAlwaysAuthenticatedVariables) / si= zeof > (mAlwaysAuthenticatedVariables[0]); Index++) { > + if ((StrCmp (VariableName, > mAlwaysAuthenticatedVariables[Index].VariableName) =3D=3D 0) && > + (CompareGuid (VendorGuid, > mAlwaysAuthenticatedVariables[Index].VendorGuid))) { > + return TRUE; > + } > + } > + return FALSE; > +} > + > +/** > + Compare two EFI_TIME data. > + > + > + @param FirstTime A pointer to the first EFI_TIME data. > + @param SecondTime A pointer to the second EFI_TIME data. > + > + @retval TRUE The FirstTime is not later than the Second= Time. > + @retval FALSE The FirstTime is later than the SecondTime= . > + > +**/ > +BOOLEAN > +VariableCompareTimeStampInternal ( > + IN EFI_TIME *FirstTime, > + IN EFI_TIME *SecondTime > + ) > +{ > + if (FirstTime->Year !=3D SecondTime->Year) { > + return (BOOLEAN) (FirstTime->Year < SecondTime->Year); > + } else if (FirstTime->Month !=3D SecondTime->Month) { > + return (BOOLEAN) (FirstTime->Month < SecondTime->Month); > + } else if (FirstTime->Day !=3D SecondTime->Day) { > + return (BOOLEAN) (FirstTime->Day < SecondTime->Day); > + } else if (FirstTime->Hour !=3D SecondTime->Hour) { > + return (BOOLEAN) (FirstTime->Hour < SecondTime->Hour); > + } else if (FirstTime->Minute !=3D SecondTime->Minute) { > + return (BOOLEAN) (FirstTime->Minute < SecondTime->Minute); > + } > + > + return (BOOLEAN) (FirstTime->Second <=3D SecondTime->Second); > +} > + > +/** > + Find the variable in the specified variable store. > + > + @param[in] VariableName Name of the variable to be found > + @param[in] VendorGuid Vendor GUID to be found. > + @param[in] IgnoreRtCheck Ignore EFI_VARIABLE_RUNTIME_ACCE= SS > attribute > + check at runtime when searching = variable. > + @param[in, out] PtrTrack Variable Track Pointer structure= that > contains Variable Information. > + > + @retval EFI_SUCCESS Variable found successfully > + @retval EFI_NOT_FOUND Variable not found > +**/ > +EFI_STATUS > +FindVariableEx ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + IN BOOLEAN IgnoreRtCheck, > + IN OUT VARIABLE_POINTER_TRACK *PtrTrack > + ) > +{ > + VARIABLE_HEADER *InDeletedVariable; > + VOID *Point; > + > + PtrTrack->InDeletedTransitionPtr =3D NULL; > + > + // > + // Find the variable by walk through HOB, volatile and non-volatile v= ariable > store. > + // > + InDeletedVariable =3D NULL; > + > + for ( PtrTrack->CurrPtr =3D PtrTrack->StartPtr > + ; IsValidVariableHeader (PtrTrack->CurrPtr, PtrTrack->EndPtr) > + ; PtrTrack->CurrPtr =3D GetNextVariablePtr (PtrTrack->CurrPtr) > + ) { > + if (PtrTrack->CurrPtr->State =3D=3D VAR_ADDED || > + PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITION & > VAR_ADDED) > + ) { > + if (IgnoreRtCheck || !AtRuntime () || ((PtrTrack->CurrPtr->Attrib= utes & > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > + if (VariableName[0] =3D=3D 0) { > + if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITIO= N & > VAR_ADDED)) { > + InDeletedVariable =3D PtrTrack->CurrPtr; > + } else { > + PtrTrack->InDeletedTransitionPtr =3D InDeletedVariable; > + return EFI_SUCCESS; > + } > + } else { > + if (CompareGuid (VendorGuid, GetVendorGuidPtr (PtrTrack->Curr= Ptr))) > { > + Point =3D (VOID *) GetVariableNamePtr (PtrTrack->CurrPtr); > + > + ASSERT (NameSizeOfVariable (PtrTrack->CurrPtr) !=3D 0); > + if (CompareMem (VariableName, Point, NameSizeOfVariable > (PtrTrack->CurrPtr)) =3D=3D 0) { > + if (PtrTrack->CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANS= ITION & > VAR_ADDED)) { > + InDeletedVariable =3D PtrTrack->CurrPtr; > + } else { > + PtrTrack->InDeletedTransitionPtr =3D InDeletedVariable; > + return EFI_SUCCESS; > + } > + } > + } > + } > + } > + } > + } > + > + PtrTrack->CurrPtr =3D InDeletedVariable; > + return (PtrTrack->CurrPtr =3D=3D NULL) ? EFI_NOT_FOUND : EFI_SUCCESS= ; > +} > + > +/** > + This code finds the next available variable. > + > + Caution: This function may receive untrusted input. > + This function may be invoked in SMM mode. This function will do basic > validation, before parse the data. > + > + @param[in] VariableName Pointer to variable name. > + @param[in] VendorGuid Variable Vendor Guid. > + @param[in] VariableStoreList A list of variable stores that should b= e used > to get the next variable. > + The maximum number of entries is the ma= x value of > VARIABLE_STORE_TYPE. > + @param[out] VariablePtr Pointer to variable header address. > + > + @retval EFI_SUCCESS The function completed successfully. > + @retval EFI_NOT_FOUND The next variable was not found. > + @retval EFI_INVALID_PARAMETER If VariableName is not an empty string, > while VendorGuid is NULL. > + @retval EFI_INVALID_PARAMETER The input values of VariableName and > VendorGuid are not a name and > + GUID of an existing variable. > + > +**/ > +EFI_STATUS > +EFIAPI > +GetNextVariableEx ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + IN VARIABLE_STORE_HEADER **VariableStoreList, > + OUT VARIABLE_HEADER **VariablePtr > + ) > +{ > + EFI_STATUS Status; > + VARIABLE_STORE_TYPE StoreType; > + VARIABLE_POINTER_TRACK Variable; > + VARIABLE_POINTER_TRACK VariableInHob; > + VARIABLE_POINTER_TRACK VariablePtrTrack; > + > + Status =3D EFI_NOT_FOUND; > + > + if (VariableStoreList =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // Check if the variable exists in the given variable store list > + for (StoreType =3D (VARIABLE_STORE_TYPE) 0; StoreType < > VariableStoreTypeMax; StoreType++) { > + if (VariableStoreList[StoreType] =3D=3D NULL) { > + continue; > + } > + > + Variable.StartPtr =3D GetStartPointer (VariableStoreList[StoreType]= ); > + Variable.EndPtr =3D GetEndPointer (VariableStoreList[StoreType]= ); > + Variable.Volatile =3D (BOOLEAN) (StoreType =3D=3D VariableStoreType= Volatile); > + > + Status =3D FindVariableEx (VariableName, VendorGuid, FALSE, &Variab= le); > + if (!EFI_ERROR (Status)) { > + break; > + } > + } > + > + if (Variable.CurrPtr =3D=3D NULL || EFI_ERROR (Status)) { > + // > + // For VariableName is an empty string, FindVariable() will try to = find and > return > + // the first qualified variable, and if FindVariable() returns erro= r > (EFI_NOT_FOUND) > + // as no any variable is found, still go to return the error > (EFI_NOT_FOUND). > + // > + if (VariableName[0] !=3D 0) { > + // > + // For VariableName is not an empty string, and FindVariable() re= turns > error as > + // VariableName and VendorGuid are not a name and GUID of an > existing variable, > + // there is no way to get next variable, follow spec to return > EFI_INVALID_PARAMETER. > + // > + Status =3D EFI_INVALID_PARAMETER; > + } > + goto Done; > + } > + > + if (VariableName[0] !=3D 0) { > + // > + // If variable name is not empty, get next variable. > + // > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > + } > + > + while (TRUE) { > + // > + // Switch to the next variable store if needed > + // > + while (!IsValidVariableHeader (Variable.CurrPtr, Variable.EndPtr)) = { > + // > + // Find current storage index > + // > + for (StoreType =3D (VARIABLE_STORE_TYPE) 0; StoreType < > VariableStoreTypeMax; StoreType++) { > + if ((VariableStoreList[StoreType] !=3D NULL) && (Variable.Start= Ptr =3D=3D > GetStartPointer (VariableStoreList[StoreType]))) { > + break; > + } > + } > + ASSERT (StoreType < VariableStoreTypeMax); > + // > + // Switch to next storage > + // > + for (StoreType++; StoreType < VariableStoreTypeMax; StoreType++) = { > + if (VariableStoreList[StoreType] !=3D NULL) { > + break; > + } > + } > + // > + // Capture the case that > + // 1. current storage is the last one, or > + // 2. no further storage > + // > + if (StoreType =3D=3D VariableStoreTypeMax) { > + Status =3D EFI_NOT_FOUND; > + goto Done; > + } > + Variable.StartPtr =3D GetStartPointer (VariableStoreList[StoreTyp= e]); > + Variable.EndPtr =3D GetEndPointer (VariableStoreList[StoreTyp= e]); > + Variable.CurrPtr =3D Variable.StartPtr; > + } > + > + // > + // Variable is found > + // > + if (Variable.CurrPtr->State =3D=3D VAR_ADDED || Variable.CurrPtr->S= tate =3D=3D > (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { > + if (!AtRuntime () || ((Variable.CurrPtr->Attributes & > EFI_VARIABLE_RUNTIME_ACCESS) !=3D 0)) { > + if (Variable.CurrPtr->State =3D=3D (VAR_IN_DELETED_TRANSITION & > VAR_ADDED)) { > + // > + // If it is a IN_DELETED_TRANSITION variable, > + // and there is also a same ADDED one at the same time, > + // don't return it. > + // > + VariablePtrTrack.StartPtr =3D Variable.StartPtr; > + VariablePtrTrack.EndPtr =3D Variable.EndPtr; > + Status =3D FindVariableEx ( > + GetVariableNamePtr (Variable.CurrPtr), > + GetVendorGuidPtr (Variable.CurrPtr), > + FALSE, > + &VariablePtrTrack > + ); > + if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr->State = =3D=3D > VAR_ADDED) { > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > + continue; > + } > + } > + > + // > + // Don't return NV variable when HOB overrides it > + // > + if ((VariableStoreList[VariableStoreTypeHob] !=3D NULL) && > (VariableStoreList[VariableStoreTypeNv] !=3D NULL) && > + (Variable.StartPtr =3D=3D GetStartPointer > (VariableStoreList[VariableStoreTypeNv])) > + ) { > + VariableInHob.StartPtr =3D GetStartPointer > (VariableStoreList[VariableStoreTypeHob]); > + VariableInHob.EndPtr =3D GetEndPointer > (VariableStoreList[VariableStoreTypeHob]); > + Status =3D FindVariableEx ( > + GetVariableNamePtr (Variable.CurrPtr), > + GetVendorGuidPtr (Variable.CurrPtr), > + FALSE, > + &VariableInHob > + ); > + if (!EFI_ERROR (Status)) { > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > + continue; > + } > + } > + > + *VariablePtr =3D Variable.CurrPtr; > + Status =3D EFI_SUCCESS; > + goto Done; > + } > + } > + > + Variable.CurrPtr =3D GetNextVariablePtr (Variable.CurrPtr); > + } > + > +Done: > + return Status; > +} > + > +/** > + Routine used to track statistical information about variable usage. > + The data is stored in the EFI system table so it can be accessed late= r. > + VariableInfo.efi can dump out the table. Only Boot Services variable > + accesses are tracked by this code. The PcdVariableCollectStatistics > + build flag controls if this feature is enabled. > + > + A read that hits in the cache will have Read and Cache true for > + the transaction. Data is allocated by this routine, but never > + freed. > + > + @param[in] VariableName Name of the Variable to track. > + @param[in] VendorGuid Guid of the Variable to track. > + @param[in] Volatile TRUE if volatile FALSE if non-volatile= . > + @param[in] Read TRUE if GetVariable() was called. > + @param[in] Write TRUE if SetVariable() was called. > + @param[in] Delete TRUE if deleted via SetVariable(). > + @param[in] Cache TRUE for a cache hit. > + @param[in,out] VariableInfo Pointer to a pointer of > VARIABLE_INFO_ENTRY structures. > + > +**/ > +VOID > +UpdateVariableInfo ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + IN BOOLEAN Volatile, > + IN BOOLEAN Read, > + IN BOOLEAN Write, > + IN BOOLEAN Delete, > + IN BOOLEAN Cache, > + IN OUT VARIABLE_INFO_ENTRY **VariableInfo > + ) > +{ > + VARIABLE_INFO_ENTRY *Entry; > + > + if (FeaturePcdGet (PcdVariableCollectStatistics)) { > + if (VariableName =3D=3D NULL || VendorGuid =3D=3D NULL || VariableI= nfo =3D=3D > NULL) { > + return; > + } > + if (AtRuntime ()) { > + // Don't collect statistics at runtime. > + return; > + } > + > + if (*VariableInfo =3D=3D NULL) { > + // > + // On the first call allocate a entry and place a pointer to it i= n > + // the EFI System Table. > + // > + *VariableInfo =3D AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY))= ; > + ASSERT (*VariableInfo !=3D NULL); > + > + CopyGuid (&(*VariableInfo)->VendorGuid, VendorGuid); > + (*VariableInfo)->Name =3D AllocateZeroPool (StrSize (VariableName= )); > + ASSERT ((*VariableInfo)->Name !=3D NULL); > + StrCpyS ((*VariableInfo)->Name, StrSize(VariableName)/sizeof(CHAR= 16), > VariableName); > + (*VariableInfo)->Volatile =3D Volatile; > + } > + > + > + for (Entry =3D (*VariableInfo); Entry !=3D NULL; Entry =3D Entry->N= ext) { > + if (CompareGuid (VendorGuid, &Entry->VendorGuid)) { > + if (StrCmp (VariableName, Entry->Name) =3D=3D 0) { > + if (Read) { > + Entry->ReadCount++; > + } > + if (Write) { > + Entry->WriteCount++; > + } > + if (Delete) { > + Entry->DeleteCount++; > + } > + if (Cache) { > + Entry->CacheCount++; > + } > + > + return; > + } > + } > + > + if (Entry->Next =3D=3D NULL) { > + // > + // If the entry is not in the table add it. > + // Next iteration of the loop will fill in the data. > + // > + Entry->Next =3D AllocateZeroPool (sizeof (VARIABLE_INFO_ENTRY))= ; > + ASSERT (Entry->Next !=3D NULL); > + > + CopyGuid (&Entry->Next->VendorGuid, VendorGuid); > + Entry->Next->Name =3D AllocateZeroPool (StrSize (VariableName))= ; > + ASSERT (Entry->Next->Name !=3D NULL); > + StrCpyS (Entry->Next->Name, StrSize(VariableName)/sizeof(CHAR16= ), > VariableName); > + Entry->Next->Volatile =3D Volatile; > + } > + } > + } > +} > + > +/** > + Initializes context needed for variable helpers. > + > + @param[in] AuthFormat If true then indicates authentic= ated > variables are supported > + > + @retval EFI_SUCCESS Initialized successfully > + @retval Others An error occurred during initial= ization > +**/ > +EFI_STATUS > +EFIAPI > +InitVariableHelpers ( > + IN BOOLEAN AuthFormat > + ) > +{ > + mAuthFormat =3D AuthFormat; > + > + return EFI_SUCCESS; > +} > diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > index ec463d063e..bda531d104 100644 > --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.c > @@ -30,6 +30,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > #include > #include "Variable.h" > +#include "VariableNonVolatile.h" > +#include "VariableParsing.h" >=20 > BOOLEAN mAtRuntime = =3D FALSE; > UINT8 *mVariableBufferPa= yload =3D NULL; > diff --git > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > index 0a1888e5ef..5bf90039d6 100644 > --- > a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > +++ > b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDx > e.c > @@ -13,7 +13,7 @@ >=20 > InitCommunicateBuffer() is really function to check the variable data= size. >=20 > -Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.
> +Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
> SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > **/ > @@ -39,6 +39,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #include >=20 > #include "PrivilegePolymorphic.h" > +#include "VariableParsing.h" >=20 > EFI_HANDLE mHandle =3D NULL; > EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable =3D NULL; > -- > 2.16.2.windows.1 >=20 >=20 >=20