MdeModulePkg Variable: Merge from Auth Variable driver in SecurityPkg

What to do:
1. Merge from Auth Variable driver in SecurityPkg to Variable drive in
MdeModulePkg. Then the merged Variable driver in MdeModulePkg will
link to AuthVariableLib and TpmMeasurementLib.
AuthVariableLibNull and TpmMeasurementLibNull in MdeModulePkg
could be used for non auth variable support.
AuthVariableLib and DxeTpmMeasurementLib in SecurityPkg
may be used for auth variable support.

Why to do:
1. Remove code duplication and reduce maintenance effort.
After auth variable service separated from Auth Variable driver in SecurityPkg
to AuthVariableLib. The remaining code logic of Auth Variable driver in SecurityPkg
will be almost same with Variable driver in MdeModulePkg. Now it is to
merge them.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17765 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Star Zeng 2015-07-01 03:08:29 +00:00 committed by lzeng14
parent c88c267d65
commit fa0737a839
16 changed files with 2357 additions and 696 deletions

View File

@ -2,12 +2,12 @@
The file defined some common structures used for communicating between SMM variable module and SMM variable wrapper module.
Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
@ -23,8 +23,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
extern EFI_GUID gSmmVariableWriteGuid;
//
// This structure is used for SMM variable. the collected statistics data is saved in SMRAM. It can be got from
// SMI handler. The communication buffer should be:
// This structure is used for SMM variable. the collected statistics data is saved in SMRAM. It can be got from
// SMI handler. The communication buffer should be:
// EFI_SMM_COMMUNICATE_HEADER + SMM_VARIABLE_COMMUNICATE_HEADER + payload.
//
typedef struct {
@ -39,26 +39,26 @@ typedef struct {
#define SMM_VARIABLE_FUNCTION_GET_VARIABLE 1
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME.
//
//
#define SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME 2
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE.
//
//
#define SMM_VARIABLE_FUNCTION_SET_VARIABLE 3
//
// The payload for this function is SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO.
//
//
#define SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO 4
//
// It is a notify event, no extra payload for this function.
//
//
#define SMM_VARIABLE_FUNCTION_READY_TO_BOOT 5
//
// It is a notify event, no extra payload for this function.
//
//
#define SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE 6
//
// The payload for this function is VARIABLE_INFO_ENTRY. The GUID in EFI_SMM_COMMUNICATE_HEADER
// The payload for this function is VARIABLE_INFO_ENTRY. The GUID in EFI_SMM_COMMUNICATE_HEADER
// is gEfiSmmVariableProtocolGuid.
//
#define SMM_VARIABLE_FUNCTION_GET_STATISTICS 7
@ -71,6 +71,8 @@ typedef struct {
#define SMM_VARIABLE_FUNCTION_VAR_CHECK_VARIABLE_PROPERTY_GET 10
#define SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE 11
///
/// Size of SMM communicate header, without including the payload.
///
@ -88,7 +90,7 @@ typedef struct {
EFI_GUID Guid;
UINTN DataSize;
UINTN NameSize;
UINT32 Attributes;
UINT32 Attributes;
CHAR16 Name[1];
} SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE;
@ -108,7 +110,7 @@ typedef struct {
UINT64 MaximumVariableStorageSize;
UINT64 RemainingVariableStorageSize;
UINT64 MaximumVariableSize;
UINT32 Attributes;
UINT32 Attributes;
} SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO;
typedef SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE;
@ -120,4 +122,8 @@ typedef struct {
CHAR16 Name[1];
} SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY;
#endif // _SMM_VARIABLE_COMMON_H_
typedef struct {
UINTN VariablePayloadSize;
} SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE;
#endif // _SMM_VARIABLE_COMMON_H_

View File

@ -0,0 +1,255 @@
/** @file
Measure TrEE required variable.
Copyright (c) 2013 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiDxe.h>
#include <Guid/ImageAuthentication.h>
#include <IndustryStandard/UefiTcgPlatform.h>
#include <Protocol/TrEEProtocol.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/TpmMeasurementLib.h>
typedef struct {
CHAR16 *VariableName;
EFI_GUID *VendorGuid;
} VARIABLE_TYPE;
VARIABLE_TYPE mVariableType[] = {
{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},
};
/**
This function will return if this variable is SecureBootPolicy Variable.
@param[in] VariableName A Null-terminated string that is the name of the vendor's variable.
@param[in] VendorGuid A unique identifier for the vendor.
@retval TRUE This is SecureBootPolicy Variable
@retval FALSE This is not SecureBootPolicy Variable
**/
BOOLEAN
IsSecureBootPolicyVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
)
{
UINTN Index;
for (Index = 0; Index < sizeof(mVariableType)/sizeof(mVariableType[0]); Index++) {
if ((StrCmp (VariableName, mVariableType[Index].VariableName) == 0) &&
(CompareGuid (VendorGuid, mVariableType[Index].VendorGuid))) {
return TRUE;
}
}
return FALSE;
}
/**
Measure and log an EFI variable, and extend the measurement result into a specific PCR.
@param[in] VarName A Null-terminated string that is the name of the vendor's variable.
@param[in] VendorGuid A unique identifier for the vendor.
@param[in] VarData The content of the variable data.
@param[in] VarSize The size of the variable data.
@retval EFI_SUCCESS Operation completed successfully.
@retval EFI_OUT_OF_RESOURCES Out of memory.
@retval EFI_DEVICE_ERROR The operation was unsuccessful.
**/
EFI_STATUS
EFIAPI
MeasureVariable (
IN CHAR16 *VarName,
IN EFI_GUID *VendorGuid,
IN VOID *VarData,
IN UINTN VarSize
)
{
EFI_STATUS Status;
UINTN VarNameLength;
EFI_VARIABLE_DATA_TREE *VarLog;
UINT32 VarLogSize;
ASSERT ((VarSize == 0 && VarData == NULL) || (VarSize != 0 && VarData != NULL));
VarNameLength = StrLen (VarName);
VarLogSize = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
- sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));
VarLog = (EFI_VARIABLE_DATA_TREE *) AllocateZeroPool (VarLogSize);
if (VarLog == NULL) {
return EFI_OUT_OF_RESOURCES;
}
CopyMem (&VarLog->VariableName, VendorGuid, sizeof(VarLog->VariableName));
VarLog->UnicodeNameLength = VarNameLength;
VarLog->VariableDataLength = VarSize;
CopyMem (
VarLog->UnicodeName,
VarName,
VarNameLength * sizeof (*VarName)
);
if (VarSize != 0) {
CopyMem (
(CHAR16 *)VarLog->UnicodeName + VarNameLength,
VarData,
VarSize
);
}
DEBUG ((EFI_D_INFO, "AuthVariableDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_AUTHORITY));
DEBUG ((EFI_D_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
Status = TpmMeasureAndLogData (
7,
EV_EFI_VARIABLE_DRIVER_CONFIG,
VarLog,
VarLogSize,
VarLog,
VarLogSize
);
FreePool (VarLog);
return Status;
}
/**
Returns the status whether get the variable success. The function retrieves
variable through the UEFI Runtime Service GetVariable(). The
returned buffer is allocated using AllocatePool(). The caller is responsible
for freeing this buffer with FreePool().
This API is only invoked in boot time. It may NOT be invoked at runtime.
@param[in] Name The pointer to a Null-terminated Unicode string.
@param[in] Guid The pointer to an EFI_GUID structure
@param[out] Value The buffer point saved the variable info.
@param[out] Size The buffer size of the variable.
@return EFI_OUT_OF_RESOURCES Allocate buffer failed.
@return EFI_SUCCESS Find the specified variable.
@return Others Errors Return errors from call to gRT->GetVariable.
**/
EFI_STATUS
InternalGetVariable (
IN CONST CHAR16 *Name,
IN CONST EFI_GUID *Guid,
OUT VOID **Value,
OUT UINTN *Size
)
{
EFI_STATUS Status;
UINTN BufferSize;
//
// Try to get the variable size.
//
BufferSize = 0;
*Value = NULL;
if (Size != NULL) {
*Size = 0;
}
Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);
if (Status != EFI_BUFFER_TOO_SMALL) {
return Status;
}
//
// Allocate buffer to get the variable.
//
*Value = AllocatePool (BufferSize);
ASSERT (*Value != NULL);
if (*Value == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// Get the variable data.
//
Status = gRT->GetVariable ((CHAR16 *) Name, (EFI_GUID *) Guid, NULL, &BufferSize, *Value);
if (EFI_ERROR (Status)) {
FreePool(*Value);
*Value = NULL;
}
if (Size != NULL) {
*Size = BufferSize;
}
return Status;
}
/**
SecureBoot Hook for SetVariable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
**/
VOID
EFIAPI
SecureBootHook (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
)
{
EFI_STATUS Status;
UINTN VariableDataSize;
VOID *VariableData;
if (!IsSecureBootPolicyVariable (VariableName, VendorGuid)) {
return ;
}
//
// We should NOT use Data and DataSize here,because it may include signature,
// or is just partial with append attributes, or is deleted.
// We should GetVariable again, to get full variable content.
//
Status = InternalGetVariable (
VariableName,
VendorGuid,
&VariableData,
&VariableDataSize
);
if (EFI_ERROR (Status)) {
VariableData = NULL;
VariableDataSize = 0;
}
Status = MeasureVariable (
VariableName,
VendorGuid,
VariableData,
VariableDataSize
);
DEBUG ((EFI_D_INFO, "MeasureBootPolicyVariable - %r\n", Status));
if (VariableData != NULL) {
FreePool (VariableData);
}
return ;
}

View File

@ -1,9 +1,8 @@
/** @file
Handles non-volatile variable store garbage collection, using FTW
(Fault Tolerant Write) protocol.
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@ -50,7 +49,7 @@ GetLbaAndOffsetByAddress (
Fvb = NULL;
*Lba = (EFI_LBA) (-1);
*Offset = 0;
//
// Get the proper FVB protocol.
//

View File

@ -2,12 +2,12 @@
Implementation functions and structures for var check protocol.
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
@ -616,30 +616,49 @@ UEFI_DEFINED_VARIABLE_ENTRY mGlobalVariableList2[] = {
},
};
typedef struct {
EFI_GUID *Guid;
CHAR16 *Name;
VAR_CHECK_VARIABLE_PROPERTY VariableProperty;
} VARIABLE_DRIVER_VARIABLE_ENTRY;
VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
//
// EFI_IMAGE_SECURITY_DATABASE_GUID
//
UEFI_DEFINED_VARIABLE_ENTRY mImageSecurityVariableList[] = {
{
&gEdkiiVarErrorFlagGuid,
VAR_ERROR_FLAG_NAME,
EFI_IMAGE_SECURITY_DATABASE,
{
VAR_CHECK_VARIABLE_PROPERTY_REVISION,
VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY,
VARIABLE_ATTRIBUTE_NV_BS_RT,
sizeof (VAR_ERROR_FLAG),
sizeof (VAR_ERROR_FLAG),
}
0,
VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
1,
MAX_UINTN
},
NULL
},
{
EFI_IMAGE_SECURITY_DATABASE1,
{
VAR_CHECK_VARIABLE_PROPERTY_REVISION,
0,
VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
1,
MAX_UINTN
},
NULL
},
{
EFI_IMAGE_SECURITY_DATABASE2,
{
VAR_CHECK_VARIABLE_PROPERTY_REVISION,
0,
VARIABLE_ATTRIBUTE_NV_BS_RT_AT,
1,
MAX_UINTN
},
NULL
},
};
/**
Get UEFI defined global variable property.
The code will check if variable guid is global variable guid first.
If yes, further check if variable name is in mGlobalVariableList or mGlobalVariableList2.
Get UEFI defined global variable or image security database variable property.
The code will check if variable guid is global variable or image security database guid first.
If yes, further check if variable name is in mGlobalVariableList, mGlobalVariableList2 or mImageSecurityVariableList.
@param[in] VariableName Pointer to variable name.
@param[in] VendorGuid Variable Vendor Guid.
@ -647,8 +666,8 @@ VARIABLE_DRIVER_VARIABLE_ENTRY mVariableDriverVariableList[] = {
@param[out] VariableProperty Pointer to variable property.
@param[out] VarCheckFunction Pointer to check function.
@retval EFI_SUCCESS Variable is not global variable.
@retval EFI_INVALID_PARAMETER Variable is global variable, but variable name is not in the lists.
@retval EFI_SUCCESS Variable is not global variable or image security database variable.
@retval EFI_INVALID_PARAMETER Variable is global variable or image security database variable, but variable name is not in the lists.
**/
EFI_STATUS
@ -711,36 +730,24 @@ GetUefiDefinedVariableProperty (
return EFI_INVALID_PARAMETER;
}
//
// It is not global variable.
//
return EFI_SUCCESS;
}
/**
Get variable property for variables managed by Varaible driver.
@param[in] VariableName Pointer to variable name.
@param[in] VendorGuid Variable Vendor Guid.
@return Pointer to variable property.
**/
VAR_CHECK_VARIABLE_PROPERTY *
GetVariableDriverVariableProperty (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
)
{
UINTN Index;
for (Index = 0; Index < sizeof (mVariableDriverVariableList)/sizeof (mVariableDriverVariableList[0]); Index++) {
if ((CompareGuid (mVariableDriverVariableList[Index].Guid, VendorGuid)) && (StrCmp (mVariableDriverVariableList[Index].Name, VariableName) == 0)) {
return &mVariableDriverVariableList[Index].VariableProperty;
if (CompareGuid (VendorGuid, &gEfiImageSecurityDatabaseGuid)) {
for (Index = 0; Index < sizeof (mImageSecurityVariableList)/sizeof (mImageSecurityVariableList[0]); Index++) {
if (StrCmp (mImageSecurityVariableList[Index].Name, VariableName) == 0) {
if (VarCheckFunction != NULL) {
*VarCheckFunction = mImageSecurityVariableList[Index].CheckFunction;
}
*VariableProperty = &mImageSecurityVariableList[Index].VariableProperty;
return EFI_SUCCESS;
}
}
return EFI_INVALID_PARAMETER;
}
return NULL;
//
// It is not global variable, image security database variable.
//
return EFI_SUCCESS;
}
/**
@ -799,13 +806,18 @@ InternalVarCheckSetVariableCheck (
break;
}
}
if (Property == NULL) {
Property = GetVariableDriverVariableProperty (VariableName, VendorGuid);
}
if (Property == NULL) {
Status = GetUefiDefinedVariableProperty (VariableName, VendorGuid, TRUE, &Property, &VarCheckFunction);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "[Variable]: Var Check UEFI defined variable fail %r - %g:%s\n", Status, VendorGuid, VariableName));
//
// 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.
//
DEBUG ((EFI_D_INFO, "Variable Check UEFI defined variable fail %r - %s not in %g namespace\n", Status, VariableName, VendorGuid));
return Status;
}
}
@ -814,27 +826,29 @@ InternalVarCheckSetVariableCheck (
DEBUG ((EFI_D_INFO, "[Variable]: Var Check ReadOnly variable fail %r - %g:%s\n", EFI_WRITE_PROTECTED, VendorGuid, VariableName));
return EFI_WRITE_PROTECTED;
}
if (!((DataSize == 0) || (Attributes == 0))) {
if (!((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0))) {
//
// Not to delete variable.
//
if (Attributes != Property->Attributes) {
DEBUG ((EFI_D_INFO, "[Variable]: Var Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
if ((Attributes != 0) && ((Attributes & (~EFI_VARIABLE_APPEND_WRITE)) != Property->Attributes)) {
DEBUG ((EFI_D_INFO, "Variable Check Attributes(0x%08x to 0x%08x) fail %r - %g:%s\n", Property->Attributes, Attributes, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
return EFI_INVALID_PARAMETER;
}
if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {
DEBUG ((EFI_D_INFO, "[Variable]: Var Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
return EFI_INVALID_PARAMETER;
}
if (VarCheckFunction != NULL) {
Status = VarCheckFunction (
Property,
DataSize,
Data
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "[Variable]: Internal Var Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
return Status;
if (DataSize != 0) {
if ((DataSize < Property->MinSize) || (DataSize > Property->MaxSize)) {
DEBUG ((EFI_D_INFO, "Variable Check DataSize fail(0x%x not in 0x%x - 0x%x) %r - %g:%s\n", DataSize, Property->MinSize, Property->MaxSize, EFI_INVALID_PARAMETER, VendorGuid, VariableName));
return EFI_INVALID_PARAMETER;
}
if (VarCheckFunction != NULL) {
Status = VarCheckFunction (
Property,
DataSize,
Data
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "Internal Variable Check function fail %r - %g:%s\n", Status, VendorGuid, VariableName));
return Status;
}
}
}
}
@ -849,7 +863,7 @@ InternalVarCheckSetVariableCheck (
Data
);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "[Variable]: Var Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));
DEBUG ((EFI_D_INFO, "Variable Check handler fail %r - %g:%s\n", Status, VendorGuid, VariableName));
return Status;
}
}
@ -875,8 +889,8 @@ ReallocateHandlerTable (
// Reallocate memory for check handler table.
//
HandlerTable = ReallocateRuntimePool (
mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
(mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
mMaxNumberOfHandler * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
(mMaxNumberOfHandler + VAR_CHECK_HANDLER_TABLE_SIZE) * sizeof (VAR_CHECK_SET_VARIABLE_CHECK_HANDLER),
mHandlerTable
);
@ -927,6 +941,10 @@ VarCheckRegisterSetVariableCheckHandler (
DEBUG ((EFI_D_INFO, "RegisterSetVariableCheckHandler - 0x%x\n", Handler));
Status = EFI_SUCCESS;
AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
//
// Check whether the handler list is enough to store new handler.
//
@ -936,7 +954,7 @@ VarCheckRegisterSetVariableCheckHandler (
//
Status = ReallocateHandlerTable();
if (EFI_ERROR (Status)) {
return Status;
goto Done;
}
}
@ -946,7 +964,10 @@ VarCheckRegisterSetVariableCheckHandler (
mHandlerTable[mNumberOfHandler] = Handler;
mNumberOfHandler++;
return EFI_SUCCESS;
Done:
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
return Status;
}
/**
@ -971,6 +992,8 @@ VariablePropertyGetFunction (
CHAR16 *VariableName;
VAR_CHECK_VARIABLE_PROPERTY *Property;
Property = NULL;
for ( Link = GetFirstNode (&mVarCheckVariableList)
; !IsNull (&mVarCheckVariableList, Link)
; Link = GetNextNode (&mVarCheckVariableList, Link)
@ -982,14 +1005,57 @@ VariablePropertyGetFunction (
}
}
Property = GetVariableDriverVariableProperty (Name, Guid);
if (Property == NULL) {
GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);
}
GetUefiDefinedVariableProperty (Name, Guid, WildcardMatch, &Property, NULL);
return Property;
}
/**
Internal variable property set.
@param[in] Name Pointer to the variable name.
@param[in] Guid Pointer to the vendor GUID.
@param[in] VariableProperty Pointer to the input variable property.
@retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
@retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
**/
EFI_STATUS
EFIAPI
InternalVarCheckVariablePropertySet (
IN CHAR16 *Name,
IN EFI_GUID *Guid,
IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
)
{
EFI_STATUS Status;
VAR_CHECK_VARIABLE_ENTRY *Entry;
CHAR16 *VariableName;
VAR_CHECK_VARIABLE_PROPERTY *Property;
Status = EFI_SUCCESS;
Property = VariablePropertyGetFunction (Name, Guid, FALSE);
if (Property != NULL) {
CopyMem (Property, VariableProperty, sizeof (*VariableProperty));
} else {
Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));
if (Entry == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
StrnCpy (VariableName, Name, StrLen (Name));
CopyGuid (&Entry->Guid, Guid);
CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));
InsertTailList (&mVarCheckVariableList, &Entry->Link);
}
Done:
return Status;
}
/**
Variable property set.
@ -1014,9 +1080,6 @@ VarCheckVariablePropertySet (
)
{
EFI_STATUS Status;
VAR_CHECK_VARIABLE_ENTRY *Entry;
CHAR16 *VariableName;
VAR_CHECK_VARIABLE_PROPERTY *Property;
if (Name == NULL || Name[0] == 0 || Guid == NULL) {
return EFI_INVALID_PARAMETER;
@ -1034,27 +1097,10 @@ VarCheckVariablePropertySet (
return EFI_ACCESS_DENIED;
}
Status = EFI_SUCCESS;
AcquireLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
Property = VariablePropertyGetFunction (Name, Guid, FALSE);
if (Property != NULL) {
CopyMem (Property, VariableProperty, sizeof (*VariableProperty));
} else {
Entry = AllocateRuntimeZeroPool (sizeof (*Entry) + StrSize (Name));
if (Entry == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
VariableName = (CHAR16 *) ((UINTN) Entry + sizeof (*Entry));
StrnCpy (VariableName, Name, StrLen (Name));
CopyGuid (&Entry->Guid, Guid);
CopyMem (&Entry->VariableProperty, VariableProperty, sizeof (*VariableProperty));
InsertTailList (&mVarCheckVariableList, &Entry->Link);
}
Status = InternalVarCheckVariablePropertySet (Name, Guid, VariableProperty);
Done:
ReleaseLockOnlyAtBootTime (&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
return Status;

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,4 @@
/** @file
The internal header file includes the common header files, defines
internal structure and functions used by Variable modules.
@ -36,14 +35,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/BaseLib.h>
#include <Library/SynchronizationLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/AuthVariableLib.h>
#include <Guid/GlobalVariable.h>
#include <Guid/EventGroup.h>
#include <Guid/VariableFormat.h>
#include <Guid/ImageAuthentication.h>
#include <Guid/SystemNvDataGuid.h>
#include <Guid/FaultTolerantWrite.h>
#include <Guid/HardwareErrorVariable.h>
#include <Guid/VarErrorFlag.h>
#define EFI_VARIABLE_ATTRIBUTES_MASK (EFI_VARIABLE_NON_VOLATILE | \
EFI_VARIABLE_BOOTSERVICE_ACCESS | \
EFI_VARIABLE_RUNTIME_ACCESS | \
EFI_VARIABLE_HARDWARE_ERROR_RECORD | \
EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \
EFI_VARIABLE_APPEND_WRITE)
///
/// The size of a 3 character ISO639 language code.
///
@ -76,6 +85,8 @@ typedef struct {
EFI_PHYSICAL_ADDRESS NonVolatileVariableBase;
EFI_LOCK VariableServicesLock;
UINT32 ReentrantState;
BOOLEAN AuthFormat;
BOOLEAN AuthSupport;
} VARIABLE_GLOBAL;
typedef struct {
@ -88,6 +99,9 @@ typedef struct {
UINTN CommonVariableTotalSize;
UINTN CommonUserVariableTotalSize;
UINTN HwErrVariableTotalSize;
UINTN MaxVariableSize;
UINTN MaxAuthVariableSize;
UINTN ScratchBufferSize;
CHAR8 *PlatformLangCodes;
CHAR8 *LangCodes;
CHAR8 *PlatformLang;
@ -135,25 +149,167 @@ FtwVariableSpace (
IN VARIABLE_STORE_HEADER *VariableBuffer
);
/**
Finds variable in storage blocks of volatile and non-volatile storage areas.
This code finds variable in storage blocks of volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
If IgnoreRtCheck is TRUE, then we ignore the EFI_VARIABLE_RUNTIME_ACCESS attribute check
at runtime when searching existing variable, only VariableName and VendorGuid are compared.
Otherwise, variables without EFI_VARIABLE_RUNTIME_ACCESS are not visible at runtime.
@param[in] VariableName Name of the variable to be found.
@param[in] VendorGuid Vendor GUID to be found.
@param[out] PtrTrack VARIABLE_POINTER_TRACK structure for output,
including the range searched and the target position.
@param[in] Global Pointer to VARIABLE_GLOBAL structure, including
base of volatile variable storage area, base of
NV variable storage area, and a lock.
@param[in] IgnoreRtCheck Ignore EFI_VARIABLE_RUNTIME_ACCESS attribute
check at runtime when searching variable.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while
VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_NOT_FOUND Variable not found
**/
EFI_STATUS
FindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VARIABLE_POINTER_TRACK *PtrTrack,
IN VARIABLE_GLOBAL *Global,
IN BOOLEAN IgnoreRtCheck
);
/**
Update the variable region with Variable information. These are the same
arguments as the EFI Variable services.
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 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[in] Marker VA_LIST style variable argument list.
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
CheckRemainingSpaceForConsistencyInternal (
IN UINT32 Attributes,
IN VA_LIST Marker
);
/**
Update the variable region with Variable information. If EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS is set,
index of associated public key is needed.
@param[in] VariableName Name of variable.
@param[in] VendorGuid Guid of variable.
@param[in] Data Variable data.
@param[in] DataSize Size of data. 0 means delete.
@param[in] Attributes Attribues of the variable.
@param[in] Attributes Attributes of the variable.
@param[in] KeyIndex Index of associated public key.
@param[in] MonotonicCount Value of associated monotonic count.
@param[in, out] Variable The variable information that is used to keep track of variable usage.
@retval EFI_SUCCESS The update operation is success.
@param[in] TimeStamp Value of associated TimeStamp.
@retval EFI_SUCCESS The update operation is success.
@retval EFI_OUT_OF_RESOURCES Variable region is full, cannot write other data into this region.
**/
@ -164,13 +320,16 @@ UpdateVariable (
IN VOID *Data,
IN UINTN DataSize,
IN UINT32 Attributes OPTIONAL,
IN OUT VARIABLE_POINTER_TRACK *Variable
IN UINT32 KeyIndex OPTIONAL,
IN UINT64 MonotonicCount OPTIONAL,
IN OUT VARIABLE_POINTER_TRACK *Variable,
IN EFI_TIME *TimeStamp OPTIONAL
);
/**
Return TRUE if ExitBootServices () has been called.
@retval TRUE If ExitBootServices () has been called.
**/
BOOLEAN
@ -181,8 +340,8 @@ AtRuntime (
/**
Initializes a basic mutual exclusion lock.
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
priority level. Since there is no preemption or multiprocessor support in EFI,
acquiring the lock only consists of raising to the locks TPL.
If Lock is NULL, then ASSERT().
@ -200,7 +359,7 @@ InitializeLock (
IN EFI_TPL Priority
);
/**
Acquires lock only at boot time. Simply returns at runtime.
@ -234,7 +393,7 @@ AcquireLockOnlyAtBootTime (
VOID
ReleaseLockOnlyAtBootTime (
IN EFI_LOCK *Lock
);
);
/**
Retrive the FVB protocol interface by HANDLE.
@ -246,7 +405,7 @@ ReleaseLockOnlyAtBootTime (
@retval EFI_SUCCESS The interface information for the specified protocol was returned.
@retval EFI_UNSUPPORTED The device does not support the FVB protocol.
@retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.
**/
EFI_STATUS
GetFvbByHandle (
@ -254,25 +413,9 @@ GetFvbByHandle (
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvBlock
);
/**
Retrive the Swap Address Range protocol interface.
@param[out] SarProtocol The interface of SAR protocol
@retval EFI_SUCCESS The SAR protocol instance was found and returned in SarProtocol.
@retval EFI_NOT_FOUND The SAR protocol instance was not found.
@retval EFI_INVALID_PARAMETER SarProtocol is NULL.
**/
EFI_STATUS
GetSarProtocol (
OUT VOID **SarProtocol
);
/**
Function returns an array of handles that support the FVB protocol
in a buffer allocated from pool.
in a buffer allocated from pool.
@param[out] NumberHandles The number of handles returned in Buffer.
@param[out] Buffer A pointer to the buffer to return the requested
@ -283,7 +426,7 @@ GetSarProtocol (
@retval EFI_NOT_FOUND No FVB handle was found.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
@retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.
**/
EFI_STATUS
GetFvbCountAndBuffer (
@ -305,13 +448,23 @@ VariableCommonInitialize (
/**
This function reclaims variable storage if free size is below the threshold.
**/
VOID
ReclaimForOS(
VOID
);
);
/**
Get non-volatile maximum variable size.
@return Non-volatile maximum variable size.
**/
UINTN
GetNonVolatileMaxVariableSize (
VOID
);
/**
Initializes variable write service after FVB was ready.
@ -324,7 +477,7 @@ EFI_STATUS
VariableWriteServiceInitialize (
VOID
);
/**
Retrive the SMM Fault Tolerent Write protocol interface.
@ -355,52 +508,21 @@ GetFvbInfoByAddress (
OUT EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL **FvbProtocol OPTIONAL
);
/**
Finds variable in storage blocks of volatile and non-volatile storage areas.
This code finds variable in storage blocks of volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
If IgnoreRtCheck is TRUE, then we ignore the EFI_VARIABLE_RUNTIME_ACCESS attribute check
at runtime when searching existing variable, only VariableName and VendorGuid are compared.
Otherwise, variables without EFI_VARIABLE_RUNTIME_ACCESS are not visible at runtime.
@param VariableName Name of the variable to be found.
@param VendorGuid Vendor GUID to be found.
@param PtrTrack VARIABLE_POINTER_TRACK structure for output,
including the range searched and the target position.
@param Global Pointer to VARIABLE_GLOBAL structure, including
base of volatile variable storage area, base of
NV variable storage area, and a lock.
@param IgnoreRtCheck Ignore EFI_VARIABLE_RUNTIME_ACCESS attribute
check at runtime when searching variable.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string, while
VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_NOT_FOUND Variable not found
**/
EFI_STATUS
FindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VARIABLE_POINTER_TRACK *PtrTrack,
IN VARIABLE_GLOBAL *Global,
IN BOOLEAN IgnoreRtCheck
);
/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
Caution: This function may receive untrusted input.
This function may be invoked in SMM mode, and datasize and data are external input.
This function will do basic validation, before parse the data.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@param Attributes Attribute value of the variable found.
@param DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param Data Data pointer.
@return EFI_INVALID_PARAMETER Invalid parameter.
@return EFI_SUCCESS Find the specified variable.
@return EFI_NOT_FOUND Not found.
@ -417,6 +539,28 @@ VariableServiceGetVariable (
OUT VOID *Data
);
/**
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.
@return EFI_SUCCESS Find the specified variable.
@return EFI_NOT_FOUND Not found.
**/
EFI_STATUS
EFIAPI
VariableServiceGetNextVariableInternal (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT VARIABLE_HEADER **VariablePtr
);
/**
This code Finds the Next available variable.
@ -449,6 +593,9 @@ VariableServiceGetNextVariableName (
Caution: This function may receive untrusted input.
This function may be invoked in SMM mode, and datasize and data are external input.
This function will do basic validation, before parse the data.
This function will parse the authentication carefully to avoid security issues, like
buffer overflow, integer overflow.
This function will check attribute carefully to avoid authentication bypass.
@param VariableName Name of Variable to be found.
@param VendorGuid Variable vendor GUID.
@ -530,7 +677,7 @@ VariableServiceQueryVariableInfo (
OUT UINT64 *MaximumVariableStorageSize,
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize
);
);
/**
Mark a variable that will become read-only after leaving the DXE phase of execution.
@ -622,6 +769,45 @@ VarCheckRegisterSetVariableCheckHandler (
IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler
);
/**
Internal variable property get.
@param[in] Name Pointer to the variable name.
@param[in] Guid Pointer to the vendor GUID.
@param[out] VariableProperty Pointer to the output variable property.
@retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
@retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
**/
EFI_STATUS
EFIAPI
InternalVarCheckVariablePropertyGet (
IN CHAR16 *Name,
IN EFI_GUID *Guid,
OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
);
/**
Internal variable property set.
@param[in] Name Pointer to the variable name.
@param[in] Guid Pointer to the vendor GUID.
@param[in] VariableProperty Pointer to the input variable property.
@retval EFI_SUCCESS The property of variable specified by the Name and Guid was set successfully.
@retval EFI_OUT_OF_RESOURCES There is not enough resource for the variable property set request.
**/
EFI_STATUS
EFIAPI
InternalVarCheckVariablePropertySet (
IN CHAR16 *Name,
IN EFI_GUID *Guid,
IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
);
/**
Variable property set.
@ -645,25 +831,6 @@ VarCheckVariablePropertySet (
IN VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
);
/**
Internal variable property get.
@param[in] Name Pointer to the variable name.
@param[in] Guid Pointer to the vendor GUID.
@param[out] VariableProperty Pointer to the output variable property.
@retval EFI_SUCCESS The property of variable specified by the Name and Guid was got successfully.
@retval EFI_NOT_FOUND The property of variable specified by the Name and Guid was not found.
**/
EFI_STATUS
EFIAPI
InternalVarCheckVariablePropertyGet (
IN CHAR16 *Name,
IN EFI_GUID *Guid,
OUT VAR_CHECK_VARIABLE_PROPERTY *VariableProperty
);
/**
Variable property get.
@ -695,4 +862,134 @@ InitializeVariableQuota (
extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
extern AUTH_VAR_LIB_CONTEXT_OUT mContextOut;
/**
Finds variable in storage blocks of volatile and non-volatile storage areas.
This code finds variable in storage blocks of volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
@param[in] VariableName Name of the variable to be found.
@param[in] VendorGuid Variable vendor GUID to be found.
@param[out] AuthVariableInfo Pointer to AUTH_VARIABLE_INFO structure for
output of the variable found.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
while VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_NOT_FOUND Variable not found
**/
EFI_STATUS
EFIAPI
VariableExLibFindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT AUTH_VARIABLE_INFO *AuthVariableInfo
);
/**
Finds next variable in storage blocks of volatile and non-volatile storage areas.
This code finds next variable in storage blocks of volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
@param[in] VariableName Name of the variable to be found.
@param[in] VendorGuid Variable vendor GUID to be found.
@param[out] AuthVariableInfo Pointer to AUTH_VARIABLE_INFO structure for
output of the next variable.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
while VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_NOT_FOUND Variable not found
**/
EFI_STATUS
EFIAPI
VariableExLibFindNextVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT AUTH_VARIABLE_INFO *AuthVariableInfo
);
/**
Update the variable region with Variable information.
@param[in] AuthVariableInfo Pointer AUTH_VARIABLE_INFO structure for
input of the variable.
@retval EFI_SUCCESS The update operation is success.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_WRITE_PROTECTED Variable is write-protected.
@retval EFI_OUT_OF_RESOURCES There is not enough resource.
**/
EFI_STATUS
EFIAPI
VariableExLibUpdateVariable (
IN AUTH_VARIABLE_INFO *AuthVariableInfo
);
/**
Get scratch buffer.
@param[in, out] ScratchBufferSize Scratch buffer size. If input size is greater than
the maximum supported buffer size, this value contains
the maximum supported buffer size as output.
@param[out] ScratchBuffer Pointer to scratch buffer address.
@retval EFI_SUCCESS Get scratch buffer successfully.
@retval EFI_UNSUPPORTED If input size is greater than the maximum supported buffer size.
**/
EFI_STATUS
EFIAPI
VariableExLibGetScratchBuffer (
IN OUT UINTN *ScratchBufferSize,
OUT VOID **ScratchBuffer
);
/**
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
VariableExLibCheckRemainingSpaceForConsistency (
IN UINT32 Attributes,
...
);
/**
Return TRUE if at OS runtime.
@retval TRUE If at OS runtime.
@retval FALSE If at boot time.
**/
BOOLEAN
EFIAPI
VariableExLibAtRuntime (
VOID
);
#endif

View File

@ -1,17 +1,16 @@
/** @file
Implement all four UEFI Runtime Variable services for the nonvolatile
and volatile storage space and install variable architecture protocol.
Copyright (C) 2013, Red Hat, Inc.
Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
@ -34,7 +33,7 @@ EDKII_VAR_CHECK_PROTOCOL mVarCheck = { VarCheckRegisterSe
/**
Return TRUE if ExitBootServices () has been called.
@retval TRUE If ExitBootServices () has been called.
**/
BOOLEAN
@ -49,8 +48,8 @@ AtRuntime (
/**
Initializes a basic mutual exclusion lock.
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
priority level. Since there is no preemption or multiprocessor support in EFI,
acquiring the lock only consists of raising to the locks TPL.
If Lock is NULL, then ASSERT().
@ -141,7 +140,7 @@ GetFtwProtocol (
&gEfiFaultTolerantWriteProtocolGuid,
NULL,
FtwProtocol
);
);
return Status;
}
@ -155,7 +154,7 @@ GetFtwProtocol (
@retval EFI_SUCCESS The interface information for the specified protocol was returned.
@retval EFI_UNSUPPORTED The device does not support the FVB protocol.
@retval EFI_INVALID_PARAMETER FvBlockHandle is not a valid EFI_HANDLE or FvBlock is NULL.
**/
EFI_STATUS
GetFvbByHandle (
@ -176,7 +175,7 @@ GetFvbByHandle (
/**
Function returns an array of handles that support the FVB protocol
in a buffer allocated from pool.
in a buffer allocated from pool.
@param[out] NumberHandles The number of handles returned in Buffer.
@param[out] Buffer A pointer to the buffer to return the requested
@ -187,7 +186,7 @@ GetFvbByHandle (
@retval EFI_NOT_FOUND No FVB handle was found.
@retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the matching results.
@retval EFI_INVALID_PARAMETER NumberHandles is NULL or Buffer is NULL.
**/
EFI_STATUS
GetFvbCountAndBuffer (
@ -246,7 +245,7 @@ VariableClassAddressChangeEvent (
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.VolatileVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->VariableGlobal.HobVariableBase);
EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
EfiConvertPointer (0x0, (VOID **) &mHandlerTable);
for (Index = 0; Index < mNumberOfHandler; Index++) {
EfiConvertPointer (0x0, (VOID **) &mHandlerTable[Index]);
@ -257,6 +256,12 @@ VariableClassAddressChangeEvent (
Status = EfiConvertList (0x0, &mVarCheckVariableList);
ASSERT_EFI_ERROR (Status);
if (mContextOut.AddressPointer != NULL) {
for (Index = 0; Index < mContextOut.AddressPointerCount; Index++) {
EfiConvertPointer (0x0, (VOID **) &mContextOut.AddressPointer[Index]);
}
}
}
@ -288,8 +293,14 @@ OnReadyToBoot (
InitializeVariableQuota ();
ReclaimForOS ();
if (FeaturePcdGet (PcdVariableCollectStatistics)) {
gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);
if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid, gVariableInfo);
} else {
gBS->InstallConfigurationTable (&gEfiVariableGuid, gVariableInfo);
}
}
gBS->CloseEvent (Event);
}
/**
@ -316,17 +327,19 @@ OnEndOfDxe (
if (PcdGetBool (PcdReclaimVariableSpaceAtEndOfDxe)) {
ReclaimForOS ();
}
gBS->CloseEvent (Event);
}
/**
Fault Tolerant Write protocol notification event handler.
Non-Volatile variable write may needs FTW protocol to reclaim when
Non-Volatile variable write may needs FTW protocol to reclaim when
writting variable.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
@ -394,21 +407,23 @@ FtwNotificationEvent (
DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.\n"));
}
}
Status = VariableWriteServiceInitialize ();
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));
}
//
// Install the Variable Write Architectural protocol.
//
Status = gBS->InstallProtocolInterface (
&mHandle,
&gEfiVariableWriteArchProtocolGuid,
&gEfiVariableWriteArchProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again.
//
@ -419,13 +434,13 @@ FtwNotificationEvent (
/**
Variable Driver main entry point. The Variable driver places the 4 EFI
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being availible. It also registers
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being available. It also registers
a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
@ -463,13 +478,13 @@ VariableServiceInitialize (
SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName;
SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable;
SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo;
//
// Now install the Variable Runtime Architectural protocol on a new handle.
//
Status = gBS->InstallProtocolInterface (
&mHandle,
&gEfiVariableArchProtocolGuid,
&gEfiVariableArchProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
@ -477,7 +492,7 @@ VariableServiceInitialize (
//
// Register FtwNotificationEvent () notify function.
//
//
EfiCreateProtocolNotifyEvent (
&gEfiFaultTolerantWriteProtocolGuid,
TPL_CALLBACK,
@ -500,9 +515,9 @@ VariableServiceInitialize (
// Register the event handling function to reclaim variable for OS usage.
//
Status = EfiCreateEventReadyToBootEx (
TPL_NOTIFY,
OnReadyToBoot,
NULL,
TPL_NOTIFY,
OnReadyToBoot,
NULL,
&ReadyToBootEvent
);
ASSERT_EFI_ERROR (Status);

View File

@ -0,0 +1,256 @@
/** @file
Provides variable driver extended services.
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Variable.h"
/**
Finds variable in storage blocks of volatile and non-volatile storage areas.
This code finds variable in storage blocks of volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
@param[in] VariableName Name of the variable to be found.
@param[in] VendorGuid Variable vendor GUID to be found.
@param[out] AuthVariableInfo Pointer to AUTH_VARIABLE_INFO structure for
output of the variable found.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
while VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_NOT_FOUND Variable not found
**/
EFI_STATUS
EFIAPI
VariableExLibFindVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT AUTH_VARIABLE_INFO *AuthVariableInfo
)
{
EFI_STATUS Status;
VARIABLE_POINTER_TRACK Variable;
AUTHENTICATED_VARIABLE_HEADER *AuthVariable;
Status = FindVariable (
VariableName,
VendorGuid,
&Variable,
&mVariableModuleGlobal->VariableGlobal,
FALSE
);
if (EFI_ERROR (Status)) {
AuthVariableInfo->Data = NULL;
AuthVariableInfo->DataSize = 0;
AuthVariableInfo->Attributes = 0;
AuthVariableInfo->PubKeyIndex = 0;
AuthVariableInfo->MonotonicCount = 0;
AuthVariableInfo->TimeStamp = NULL;
return Status;
}
AuthVariableInfo->DataSize = DataSizeOfVariable (Variable.CurrPtr);
AuthVariableInfo->Data = GetVariableDataPtr (Variable.CurrPtr);
AuthVariableInfo->Attributes = Variable.CurrPtr->Attributes;
if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable.CurrPtr;
AuthVariableInfo->PubKeyIndex = AuthVariable->PubKeyIndex;
AuthVariableInfo->MonotonicCount = AuthVariable->MonotonicCount;
AuthVariableInfo->TimeStamp = &AuthVariable->TimeStamp;
}
return EFI_SUCCESS;
}
/**
Finds next variable in storage blocks of volatile and non-volatile storage areas.
This code finds next variable in storage blocks of volatile and non-volatile storage areas.
If VariableName is an empty string, then we just return the first
qualified variable without comparing VariableName and VendorGuid.
@param[in] VariableName Name of the variable to be found.
@param[in] VendorGuid Variable vendor GUID to be found.
@param[out] AuthVariableInfo Pointer to AUTH_VARIABLE_INFO structure for
output of the next variable.
@retval EFI_INVALID_PARAMETER If VariableName is not an empty string,
while VendorGuid is NULL.
@retval EFI_SUCCESS Variable successfully found.
@retval EFI_NOT_FOUND Variable not found
**/
EFI_STATUS
EFIAPI
VariableExLibFindNextVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT AUTH_VARIABLE_INFO *AuthVariableInfo
)
{
EFI_STATUS Status;
VARIABLE_HEADER *VariablePtr;
AUTHENTICATED_VARIABLE_HEADER *AuthVariablePtr;
Status = VariableServiceGetNextVariableInternal (
VariableName,
VendorGuid,
&VariablePtr
);
if (EFI_ERROR (Status)) {
AuthVariableInfo->VariableName = NULL;
AuthVariableInfo->VendorGuid = NULL;
AuthVariableInfo->Data = NULL;
AuthVariableInfo->DataSize = 0;
AuthVariableInfo->Attributes = 0;
AuthVariableInfo->PubKeyIndex = 0;
AuthVariableInfo->MonotonicCount = 0;
AuthVariableInfo->TimeStamp = NULL;
return Status;
}
AuthVariableInfo->VariableName = GetVariableNamePtr (VariablePtr);
AuthVariableInfo->VendorGuid = GetVendorGuidPtr (VariablePtr);
AuthVariableInfo->DataSize = DataSizeOfVariable (VariablePtr);
AuthVariableInfo->Data = GetVariableDataPtr (VariablePtr);
AuthVariableInfo->Attributes = VariablePtr->Attributes;
if (mVariableModuleGlobal->VariableGlobal.AuthFormat) {
AuthVariablePtr = (AUTHENTICATED_VARIABLE_HEADER *) VariablePtr;
AuthVariableInfo->PubKeyIndex = AuthVariablePtr->PubKeyIndex;
AuthVariableInfo->MonotonicCount = AuthVariablePtr->MonotonicCount;
AuthVariableInfo->TimeStamp = &AuthVariablePtr->TimeStamp;
}
return EFI_SUCCESS;
}
/**
Update the variable region with Variable information.
@param[in] AuthVariableInfo Pointer AUTH_VARIABLE_INFO structure for
input of the variable.
@retval EFI_SUCCESS The update operation is success.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_WRITE_PROTECTED Variable is write-protected.
@retval EFI_OUT_OF_RESOURCES There is not enough resource.
**/
EFI_STATUS
EFIAPI
VariableExLibUpdateVariable (
IN AUTH_VARIABLE_INFO *AuthVariableInfo
)
{
VARIABLE_POINTER_TRACK Variable;
FindVariable (AuthVariableInfo->VariableName, AuthVariableInfo->VendorGuid, &Variable, &mVariableModuleGlobal->VariableGlobal, FALSE);
return UpdateVariable (
AuthVariableInfo->VariableName,
AuthVariableInfo->VendorGuid,
AuthVariableInfo->Data,
AuthVariableInfo->DataSize,
AuthVariableInfo->Attributes,
AuthVariableInfo->PubKeyIndex,
AuthVariableInfo->MonotonicCount,
&Variable,
AuthVariableInfo->TimeStamp
);
}
/**
Get scratch buffer.
@param[in, out] ScratchBufferSize Scratch buffer size. If input size is greater than
the maximum supported buffer size, this value contains
the maximum supported buffer size as output.
@param[out] ScratchBuffer Pointer to scratch buffer address.
@retval EFI_SUCCESS Get scratch buffer successfully.
@retval EFI_UNSUPPORTED If input size is greater than the maximum supported buffer size.
**/
EFI_STATUS
EFIAPI
VariableExLibGetScratchBuffer (
IN OUT UINTN *ScratchBufferSize,
OUT VOID **ScratchBuffer
)
{
UINTN MaxBufferSize;
MaxBufferSize = mVariableModuleGlobal->ScratchBufferSize;
if (*ScratchBufferSize > MaxBufferSize) {
*ScratchBufferSize = MaxBufferSize;
return EFI_UNSUPPORTED;
}
*ScratchBuffer = GetEndPointer ((VARIABLE_STORE_HEADER *) ((UINTN) mVariableModuleGlobal->VariableGlobal.VolatileVariableBase));
return EFI_SUCCESS;
}
/**
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
VariableExLibCheckRemainingSpaceForConsistency (
IN UINT32 Attributes,
...
)
{
VA_LIST Marker;
BOOLEAN Return;
VA_START (Marker, Attributes);
Return = CheckRemainingSpaceForConsistencyInternal (Attributes, Marker);
VA_END (Marker);
return Return;
}
/**
Return TRUE if at OS runtime.
@retval TRUE If at OS runtime.
@retval FALSE If at boot time.
**/
BOOLEAN
EFIAPI
VariableExLibAtRuntime (
VOID
)
{
return AtRuntime ();
}

View File

@ -1,7 +1,8 @@
## @file
# This module installs variable arch protocol and variable write arch protocol.
# Provides variable service.
#
# It provides four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo.
# This module installs variable arch protocol and variable write arch protocol to provide
# variable services: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo.
#
# Caution: This module requires additional review when modified.
# This driver will have external input - variable data.
@ -9,14 +10,12 @@
# buffer overflow or integer overflow.
#
# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
@ -42,7 +41,9 @@
Variable.c
VariableDxe.c
Variable.h
Measurement.c
VarCheck.c
VariableExLib.c
[Packages]
MdePkg/MdePkg.dec
@ -62,6 +63,8 @@
PcdLib
HobLib
DevicePathLib
TpmMeasurementLib
AuthVariableLib
[Protocols]
gEfiFirmwareVolumeBlockProtocolGuid ## CONSUMES
@ -74,23 +77,41 @@
gEdkiiVarCheckProtocolGuid ## PRODUCES
[Guids]
## PRODUCES ## GUID # Signature of Variable store header
## CONSUMES ## GUID # Signature of Variable store header
## SOMETIMES_CONSUMES ## HOB
## SOMETIMES_PRODUCES ## SystemTable
gEfiAuthenticatedVariableGuid
## PRODUCES ## GUID # Signature of Variable store header
## CONSUMES ## GUID # Signature of Variable store header
## SOMETIMES_CONSUMES ## HOB
## SOMETIMES_PRODUCES ## SystemTable
gEfiVariableGuid
## SOMETIMES_CONSUMES ## Variable:L"PlatformLang"
## SOMETIMES_PRODUCES ## Variable:L"PlatformLang"
## SOMETIMES_CONSUMES ## Variable:L"Lang"
## SOMETIMES_PRODUCES ## Variable:L"Lang"
## SOMETIMES_CONSUMES ## Variable:L"HwErrRecSupport"
## SOMETIMES_CONSUMES ## Variable:L"SetupMode"
## SOMETIMES_CONSUMES ## Variable:L"PK"
## SOMETIMES_CONSUMES ## Variable:L"KEK"
## SOMETIMES_CONSUMES ## Variable:L"SecureBoot"
## SOMETIMES_CONSUMES ## Variable:L"SignatureSupport"
## SOMETIMES_CONSUMES ## Variable:L"VendorKeys"
gEfiGlobalVariableGuid
## SOMETIMES_CONSUMES ## Variable:L"DB"
## SOMETIMES_CONSUMES ## Variable:L"DBX"
## SOMETIMES_CONSUMES ## Variable:L"DBT"
gEfiImageSecurityDatabaseGuid
gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
gEfiSystemNvDataFvGuid ## CONSUMES ## GUID
gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES ## Variable:L"HwErrRec####"
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
## SOMETIMES_CONSUMES ## HOB
gEdkiiFaultTolerantWriteGuid
gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB
gEdkiiVarErrorFlagGuid ## CONSUMES ## GUID
[Pcd]
@ -98,6 +119,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES
@ -107,7 +129,7 @@
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang
[Depex]
TRUE

View File

@ -1,7 +1,6 @@
/** @file
The sample implementation for SMM variable protocol. And this driver
implements an SMI handler to communicate with the DXE runtime driver
The sample implementation for SMM variable protocol. And this driver
implements an SMI handler to communicate with the DXE runtime driver
to provide variable services.
Caution: This module requires additional review when modified.
@ -11,20 +10,21 @@
SmmVariableHandler() will receive untrusted input and do basic validation.
Each sub function VariableServiceGetVariable(), VariableServiceGetNextVariableName(),
VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),
Each sub function VariableServiceGetVariable(), VariableServiceGetNextVariableName(),
VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),
SmmVariableGetStatistics() should also do validation based on its own knowledge.
Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Protocol/SmmVariable.h>
#include <Protocol/SmmFirmwareVolumeBlock.h>
#include <Protocol/SmmFaultTolerantWrite.h>
@ -34,7 +34,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/SmmServicesTableLib.h>
#include <Library/SmmMemLib.h>
#include <Guid/VariableFormat.h>
#include <Guid/SmmVariableCommon.h>
#include "Variable.h"
@ -48,6 +47,23 @@ UINTN mVariableBufferPayloadSize;
extern BOOLEAN mEndOfDxe;
extern BOOLEAN mEnableLocking;
/**
SecureBoot Hook for SetVariable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
**/
VOID
EFIAPI
SecureBootHook (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
)
{
return ;
}
/**
This code sets variable in storage blocks (Volatile or Non-Volatile).
@ -106,7 +122,7 @@ EDKII_SMM_VAR_CHECK_PROTOCOL mSmmVarCheck = { VarCheckRegisterSetVariableCheckHa
/**
Return TRUE if ExitBootServices () has been called.
@retval TRUE If ExitBootServices () has been called.
**/
BOOLEAN
@ -120,8 +136,8 @@ AtRuntime (
/**
Initializes a basic mutual exclusion lock.
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
This function initializes a basic mutual exclusion lock to the released state
and returns the lock. Each lock provides mutual exclusion access at its task
priority level. Since there is no preemption or multiprocessor support in EFI,
acquiring the lock only consists of raising to the locks TPL.
If Lock is NULL, then ASSERT().
@ -204,8 +220,8 @@ GetFtwProtocol (
// Locate Smm Fault Tolerent Write protocol
//
Status = gSmst->SmmLocateProtocol (
&gEfiSmmFaultTolerantWriteProtocolGuid,
NULL,
&gEfiSmmFaultTolerantWriteProtocolGuid,
NULL,
FtwProtocol
);
return Status;
@ -243,7 +259,7 @@ GetFvbByHandle (
/**
Function returns an array of handles that support the SMM FVB protocol
in a buffer allocated from pool.
in a buffer allocated from pool.
@param[out] NumberHandles The number of handles returned in Buffer.
@param[out] Buffer A pointer to the buffer to return the requested
@ -314,16 +330,17 @@ GetFvbCountAndBuffer (
InfoEntry and InfoSize are external input. Care must be taken to make sure not security issue at runtime.
@param[in, out] InfoEntry A pointer to the buffer of variable information entry.
On input, point to the variable information returned last time. if
On input, point to the variable information returned last time. if
InfoEntry->VendorGuid is zero, return the first information.
On output, point to the next variable information.
@param[in, out] InfoSize On input, the size of the variable information buffer.
On output, the returned variable information size.
@retval EFI_SUCCESS The variable information is found and returned successfully.
@retval EFI_UNSUPPORTED No variable inoformation exists in variable driver. The
PcdVariableCollectStatistics should be set TRUE to support it.
@retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the next variable information.
@retval EFI_SUCCESS The variable information is found and returned successfully.
@retval EFI_UNSUPPORTED No variable inoformation exists in variable driver. The
PcdVariableCollectStatistics should be set TRUE to support it.
@retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the next variable information.
@retval EFI_INVALID_PARAMETER Input parameter is invalid.
**/
EFI_STATUS
@ -338,8 +355,11 @@ SmmVariableGetStatistics (
CHAR16 *InfoName;
EFI_GUID VendorGuid;
ASSERT (InfoEntry != NULL);
VariableInfo = gVariableInfo;
if (InfoEntry == NULL) {
return EFI_INVALID_PARAMETER;
}
VariableInfo = gVariableInfo;
if (VariableInfo == NULL) {
return EFI_UNSUPPORTED;
}
@ -381,7 +401,7 @@ SmmVariableGetStatistics (
}
VariableInfo = VariableInfo->Next;
};
if (VariableInfo == NULL) {
*InfoSize = 0;
return EFI_SUCCESS;
@ -399,7 +419,7 @@ SmmVariableGetStatistics (
CopyMem (InfoEntry, VariableInfo, sizeof (VARIABLE_INFO_ENTRY));
CopyMem (InfoName, VariableInfo->Name, StrSize (VariableInfo->Name));
*InfoSize = StatisticsInfoSize;
return EFI_SUCCESS;
}
@ -411,8 +431,8 @@ SmmVariableGetStatistics (
Caution: This function may receive untrusted input.
This variable data and communicate buffer are external input, so this function will do basic validation.
Each sub function VariableServiceGetVariable(), VariableServiceGetNextVariableName(),
VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),
Each sub function VariableServiceGetVariable(), VariableServiceGetNextVariableName(),
VariableServiceSetVariable(), VariableServiceQueryVariableInfo(), ReclaimForOS(),
SmmVariableGetStatistics() should also do validation based on its own knowledge.
@param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
@ -422,11 +442,11 @@ SmmVariableGetStatistics (
be conveyed from a non-SMM environment into an SMM environment.
@param[in, out] CommBufferSize The size of the CommBuffer.
@retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
@retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
should still be called.
@retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
@retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
still be called.
@retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
@retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
be called.
@retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
**/
@ -444,6 +464,7 @@ SmmVariableHandler (
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *SmmVariableHeader;
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *GetNextVariableName;
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;
SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE *GetPayloadSize;
VARIABLE_INFO_ENTRY *VariableInfo;
SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock;
SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY *CommVariableProperty;
@ -496,7 +517,7 @@ SmmVariableHandler (
Status = EFI_ACCESS_DENIED;
goto EXIT;
}
InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)
InfoSize = OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)
+ SmmVariableHeader->DataSize + SmmVariableHeader->NameSize;
//
@ -525,7 +546,7 @@ SmmVariableHandler (
);
CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);
break;
case SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME:
if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name)) {
DEBUG ((EFI_D_ERROR, "GetNextVariableName: SMM communication buffer size invalid!\n"));
@ -570,7 +591,7 @@ SmmVariableHandler (
);
CopyMem (SmmVariableFunctionHeader->Data, mVariableBufferPayload, CommBufferPayloadSize);
break;
case SMM_VARIABLE_FUNCTION_SET_VARIABLE:
if (CommBufferPayloadSize < OFFSET_OF(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE, Name)) {
DEBUG ((EFI_D_ERROR, "SetVariable: SMM communication buffer size invalid!\n"));
@ -618,7 +639,7 @@ SmmVariableHandler (
(UINT8 *)SmmVariableHeader->Name + SmmVariableHeader->NameSize
);
break;
case SMM_VARIABLE_FUNCTION_QUERY_VARIABLE_INFO:
if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO)) {
DEBUG ((EFI_D_ERROR, "QueryVariableInfo: SMM communication buffer size invalid!\n"));
@ -634,6 +655,16 @@ SmmVariableHandler (
);
break;
case SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE:
if (CommBufferPayloadSize < sizeof (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE)) {
DEBUG ((EFI_D_ERROR, "GetPayloadSize: SMM communication buffer size invalid!\n"));
return EFI_SUCCESS;
}
GetPayloadSize = (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE *) SmmVariableFunctionHeader->Data;
GetPayloadSize->VariablePayloadSize = mVariableBufferPayloadSize;
Status = EFI_SUCCESS;
break;
case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
mEndOfDxe = TRUE;
//
@ -647,7 +678,7 @@ SmmVariableHandler (
ReclaimForOS ();
Status = EFI_SUCCESS;
break;
case SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE:
mAtRuntime = TRUE;
Status = EFI_SUCCESS;
@ -658,15 +689,15 @@ SmmVariableHandler (
InfoSize = TempCommBufferSize - SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
//
// Do not need to check SmmVariableFunctionHeader->Data in SMRAM here.
// It is covered by previous CommBuffer check
// Do not need to check SmmVariableFunctionHeader->Data in SMRAM here.
// It is covered by previous CommBuffer check
//
if (!SmmIsBufferOutsideSmmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBufferSize, sizeof(UINTN))) {
DEBUG ((EFI_D_ERROR, "GetStatistics: SMM communication buffer in SMRAM!\n"));
Status = EFI_ACCESS_DENIED;
goto EXIT;
}
}
Status = SmmVariableGetStatistics (VariableInfo, &InfoSize);
*CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
@ -784,16 +815,16 @@ SmmEndOfDxeCallback (
/**
SMM Fault Tolerant Write protocol notification event handler.
Non-Volatile variable write may needs FTW protocol to reclaim when
Non-Volatile variable write may needs FTW protocol to reclaim when
writting variable.
@param Protocol Points to the protocol's unique identifier
@param Interface Points to the interface instance
@param Handle The handle on which the interface was installed
@retval EFI_SUCCESS SmmEventCallback runs successfully
@retval EFI_NOT_FOUND The Fvb protocol for variable is not found.
**/
EFI_STATUS
EFIAPI
@ -808,7 +839,7 @@ SmmFtwNotificationEvent (
EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol;
EFI_PHYSICAL_ADDRESS NvStorageVariableBase;
UINTN FtwMaxBlockSize;
if (mVariableModuleGlobal->FvbInstance != NULL) {
return EFI_SUCCESS;
}
@ -839,10 +870,12 @@ SmmFtwNotificationEvent (
}
mVariableModuleGlobal->FvbInstance = FvbProtocol;
Status = VariableWriteServiceInitialize ();
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Variable write service initialization failed. Status = %r\n", Status));
}
//
// Notify the variable wrapper driver the variable write service is ready
//
@ -853,20 +886,20 @@ SmmFtwNotificationEvent (
NULL
);
ASSERT_EFI_ERROR (Status);
return EFI_SUCCESS;
}
/**
Variable Driver main entry point. The Variable driver places the 4 EFI
runtime services in the EFI System Table and installs arch protocols
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being available. It also registers
a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
@ -908,8 +941,8 @@ VariableServiceInitialize (
);
ASSERT_EFI_ERROR (Status);
mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +
OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER);
mVariableBufferPayloadSize = GetNonVolatileMaxVariableSize () +
OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - GetVariableHeaderSize ();
Status = gSmst->SmmAllocatePool (
EfiRuntimeServicesData,
@ -924,7 +957,7 @@ VariableServiceInitialize (
VariableHandle = NULL;
Status = gSmst->SmiHandlerRegister (SmmVariableHandler, &gEfiSmmVariableProtocolGuid, &VariableHandle);
ASSERT_EFI_ERROR (Status);
//
// Notify the variable wrapper driver the variable service is ready
//
@ -935,7 +968,7 @@ VariableServiceInitialize (
&gSmmVariable
);
ASSERT_EFI_ERROR (Status);
//
// Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.
//
@ -948,7 +981,7 @@ VariableServiceInitialize (
//
// Register FtwNotificationEvent () notify function.
//
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmFaultTolerantWriteProtocolGuid,
SmmFtwNotificationEvent,
@ -957,7 +990,7 @@ VariableServiceInitialize (
ASSERT_EFI_ERROR (Status);
SmmFtwNotificationEvent (NULL, NULL, NULL);
return EFI_SUCCESS;
}

View File

@ -1,16 +1,22 @@
## @file
# Provides SMM variable service.
#
# This module installs SMM variable protocol into SMM protocol database,
# which can be used by SMM driver, and installs SMM variable protocol
# which can be used by SMM driver, and installs SMM variable protocol
# into BS protocol database, which can be used to notify the SMM Runtime
# Dxe driver that the SMM variable service is ready.
# This module should be used with SMM Runtime DXE module together. The
# SMM Runtime DXE module would install variable arch protocol and variable
# This module should be used with SMM Runtime DXE module together. The
# SMM Runtime DXE module would install variable arch protocol and variable
# write arch protocol based on SMM variable module.
#
# Caution: This module requires additional review when modified.
# This driver will have external input - variable data and communicate buffer in SMM mode.
# This external input must be validated carefully to avoid security issue like
# buffer overflow, integer overflow.
# This external input must be validated carefully to avoid security issues such as
# buffer overflow or integer overflow.
# The whole SMM authentication variable design relies on the integrity of flash part and SMM.
# which is assumed to be protected by platform. All variable code and metadata in flash/SMM Memory
# may not be modified without authorization. If platform fails to protect these resources,
# the authentication service provided in this driver will be broken, and the behavior is undefined.
#
# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
@ -20,7 +26,6 @@
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
##
[Defines]
@ -46,6 +51,7 @@
VariableSmm.c
VarCheck.c
Variable.h
VariableExLib.c
[Packages]
MdePkg/MdePkg.dec
@ -65,6 +71,7 @@
PcdLib
DevicePathLib
SmmMemLib
AuthVariableLib
[Protocols]
gEfiSmmFirmwareVolumeBlockProtocolGuid ## CONSUMES
@ -81,35 +88,55 @@
## PRODUCES ## GUID # Signature of Variable store header
## CONSUMES ## GUID # Signature of Variable store header
## SOMETIMES_CONSUMES ## HOB
## SOMETIMES_PRODUCES ## SystemTable
gEfiAuthenticatedVariableGuid
## PRODUCES ## GUID # Signature of Variable store header
## CONSUMES ## GUID # Signature of Variable store header
## SOMETIMES_CONSUMES ## HOB
## SOMETIMES_PRODUCES ## SystemTable
gEfiVariableGuid
## SOMETIMES_CONSUMES ## Variable:L"PlatformLang"
## SOMETIMES_PRODUCES ## Variable:L"PlatformLang"
## SOMETIMES_CONSUMES ## Variable:L"Lang"
## SOMETIMES_PRODUCES ## Variable:L"Lang"
## SOMETIMES_CONSUMES ## Variable:L"HwErrRecSupport"
## SOMETIMES_CONSUMES ## Variable:L"SetupMode"
## SOMETIMES_CONSUMES ## Variable:L"PK"
## SOMETIMES_CONSUMES ## Variable:L"KEK"
## SOMETIMES_CONSUMES ## Variable:L"SecureBoot"
## SOMETIMES_CONSUMES ## Variable:L"SignatureSupport"
## SOMETIMES_CONSUMES ## Variable:L"VendorKeys"
gEfiGlobalVariableGuid
gSmmVariableWriteGuid ## PRODUCES ## UNDEFINED # Install protocol
## SOMETIMES_CONSUMES ## Variable:L"DB"
## SOMETIMES_CONSUMES ## Variable:L"DBX"
## SOMETIMES_CONSUMES ## Variable:L"DBT"
gEfiImageSecurityDatabaseGuid
gSmmVariableWriteGuid ## PRODUCES ## GUID # Install protocol
gEfiSystemNvDataFvGuid ## CONSUMES ## GUID
gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES ## Variable:L"HwErrRec####"
## SOMETIMES_CONSUMES ## HOB
gEdkiiFaultTolerantWriteGuid
gEdkiiFaultTolerantWriteGuid ## SOMETIMES_CONSUMES ## HOB
gEdkiiVarErrorFlagGuid ## CONSUMES ## GUID
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxUserNvVariableSpaceSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdBoottimeReservedNvVariableSpaceSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe ## CONSUMES
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable.
gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang
[Depex]
TRUE

View File

@ -1,5 +1,4 @@
/** @file
Implement all four UEFI Runtime Variable services for the nonvolatile
and volatile storage space and install variable architecture protocol
based on SMM variable module.
@ -15,13 +14,13 @@
InitCommunicateBuffer() is really function to check the variable data size.
Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <PiDxe.h>
@ -39,15 +38,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/UefiRuntimeLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiLib.h>
#include <Library/BaseLib.h>
#include <Guid/EventGroup.h>
#include <Guid/VariableFormat.h>
#include <Guid/SmmVariableCommon.h>
EFI_HANDLE mHandle = NULL;
EFI_HANDLE mHandle = NULL;
EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable = NULL;
EFI_EVENT mVirtualAddressChangeEvent = NULL;
EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
@ -59,6 +56,20 @@ EFI_LOCK mVariableServicesLock;
EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock;
EDKII_VAR_CHECK_PROTOCOL mVarCheck;
/**
SecureBoot Hook for SetVariable.
@param[in] VariableName Name of Variable to be found.
@param[in] VendorGuid Variable vendor GUID.
**/
VOID
EFIAPI
SecureBootHook (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid
);
/**
Acquires lock only at boot time. Simply returns at runtime.
@ -115,7 +126,7 @@ ReleaseLockOnlyAtBootTime (
@param[out] DataPtr Points to the data in the communicate buffer.
@param[in] DataSize The data size to send to SMM.
@param[in] Function The function number to initialize the communicate header.
@retval EFI_INVALID_PARAMETER The data size is too big.
@retval EFI_SUCCESS Find the specified variable.
@ -127,10 +138,10 @@ InitCommunicateBuffer (
IN UINTN Function
)
{
EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
if (DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE > mVariableBufferSize) {
return EFI_INVALID_PARAMETER;
}
@ -138,7 +149,7 @@ InitCommunicateBuffer (
SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) mVariableBuffer;
CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);
SmmCommunicateHeader->MessageLength = DataSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) SmmCommunicateHeader->Data;
SmmVariableFunctionHeader->Function = Function;
if (DataPtr != NULL) {
@ -155,8 +166,8 @@ InitCommunicateBuffer (
@param[in] DataSize This size of the function header and the data.
@retval EFI_SUCCESS Success is returned from the functin in SMM.
@retval Others Failure is returned from the function in SMM.
@retval Others Failure is returned from the function in SMM.
**/
EFI_STATUS
SendCommunicateBuffer (
@ -165,9 +176,9 @@ SendCommunicateBuffer (
{
EFI_STATUS Status;
UINTN CommSize;
EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
CommSize = DataSize + SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
Status = mSmmCommunication->Communicate (mSmmCommunication, mVariableBufferPhysical, &CommSize);
ASSERT_EFI_ERROR (Status);
@ -432,7 +443,7 @@ Done:
@param[in, out] DataSize Size of Data found. If size is less than the
data, this value contains the required size.
@param[out] Data Data pointer.
@retval EFI_INVALID_PARAMETER Invalid parameter.
@retval EFI_SUCCESS Find the specified variable.
@retval EFI_NOT_FOUND Not found.
@ -594,7 +605,6 @@ RuntimeServiceGetNextVariableName (
//
PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME, Name) + MAX (OutVariableNameSize, InVariableNameSize);
Status = InitCommunicateBuffer ((VOID **)&SmmGetNextVariableName, PayloadSize, SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME);
if (EFI_ERROR (Status)) {
goto Done;
@ -633,9 +643,9 @@ RuntimeServiceGetNextVariableName (
if (EFI_ERROR (Status)) {
goto Done;
}
CopyGuid (VendorGuid, &SmmGetNextVariableName->Guid);
CopyMem (VariableName, SmmGetNextVariableName->Name, SmmGetNextVariableName->NameSize);
CopyMem (VariableName, SmmGetNextVariableName->Name, SmmGetNextVariableName->NameSize);
Done:
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
@ -673,16 +683,16 @@ RuntimeServiceSetVariable (
)
{
EFI_STATUS Status;
UINTN PayloadSize;
UINTN PayloadSize;
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *SmmVariableHeader;
UINTN VariableNameSize;
//
// Check input parameters.
//
if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
return EFI_INVALID_PARAMETER;
}
}
if (DataSize != 0 && Data == NULL) {
return EFI_INVALID_PARAMETER;
@ -700,7 +710,7 @@ RuntimeServiceSetVariable (
}
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
@ -726,6 +736,15 @@ RuntimeServiceSetVariable (
Done:
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
if (!EfiAtRuntime ()) {
if (!EFI_ERROR (Status)) {
SecureBootHook (
VariableName,
VendorGuid
);
}
}
return Status;
}
@ -794,7 +813,7 @@ RuntimeServiceQueryVariableInfo (
//
*MaximumVariableSize = SmmQueryVariableInfo->MaximumVariableSize;
*MaximumVariableStorageSize = SmmQueryVariableInfo->MaximumVariableStorageSize;
*RemainingVariableStorageSize = SmmQueryVariableInfo->RemainingVariableStorageSize;
*RemainingVariableStorageSize = SmmQueryVariableInfo->RemainingVariableStorageSize;
Done:
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
@ -822,7 +841,7 @@ OnExitBootServices (
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE.
//
InitCommunicateBuffer (NULL, 0, SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE);
InitCommunicateBuffer (NULL, 0, SMM_VARIABLE_FUNCTION_EXIT_BOOT_SERVICE);
//
// Send data to SMM.
@ -852,11 +871,13 @@ OnReadyToBoot (
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE.
//
InitCommunicateBuffer (NULL, 0, SMM_VARIABLE_FUNCTION_READY_TO_BOOT);
//
// Send data to SMM.
//
SendCommunicateBuffer (0);
gBS->CloseEvent (Event);
}
@ -881,13 +902,86 @@ VariableAddressChangeEvent (
EfiConvertPointer (0x0, (VOID **) &mSmmCommunication);
}
/**
This code gets variable payload size.
@param[out] VariablePayloadSize Output pointer to variable payload size.
@retval EFI_SUCCESS Get successfully.
@retval Others Get unsuccessfully.
**/
EFI_STATUS
EFIAPI
GetVariablePayloadSize (
OUT UINTN *VariablePayloadSize
)
{
EFI_STATUS Status;
SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE *SmmGetPayloadSize;
EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;
UINTN CommSize;
UINT8 *CommBuffer;
SmmGetPayloadSize = NULL;
CommBuffer = NULL;
if(VariablePayloadSize == NULL) {
return EFI_INVALID_PARAMETER;
}
AcquireLockOnlyAtBootTime(&mVariableServicesLock);
//
// Init the communicate buffer. The buffer data size is:
// SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + sizeof (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE);
//
CommSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + sizeof (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE);
CommBuffer = AllocateZeroPool (CommSize);
if (CommBuffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *) CommBuffer;
CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);
SmmCommunicateHeader->MessageLength = SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + sizeof (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE);
SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) SmmCommunicateHeader->Data;
SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_GET_PAYLOAD_SIZE;
SmmGetPayloadSize = (SMM_VARIABLE_COMMUNICATE_GET_PAYLOAD_SIZE *) SmmVariableFunctionHeader->Data;
//
// Send data to SMM.
//
Status = mSmmCommunication->Communicate (mSmmCommunication, CommBuffer, &CommSize);
ASSERT_EFI_ERROR (Status);
Status = SmmVariableFunctionHeader->ReturnStatus;
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Get data from SMM.
//
*VariablePayloadSize = SmmGetPayloadSize->VariablePayloadSize;
Done:
if (CommBuffer != NULL) {
FreePool (CommBuffer);
}
ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
return Status;
}
/**
Initialize variable service and install Variable Architectural protocol.
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
@ -902,15 +996,15 @@ SmmVariableReady (
if (EFI_ERROR (Status)) {
return;
}
Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
ASSERT_EFI_ERROR (Status);
//
// Allocate memory for variable communicate buffer.
//
mVariableBufferPayloadSize = MAX (PcdGet32 (PcdMaxVariableSize), PcdGet32 (PcdMaxHardwareErrorVariableSize)) +
OFFSET_OF (SMM_VARIABLE_COMMUNICATE_VAR_CHECK_VARIABLE_PROPERTY, Name) - sizeof (VARIABLE_HEADER);
Status = GetVariablePayloadSize (&mVariableBufferPayloadSize);
ASSERT_EFI_ERROR (Status);
mVariableBufferSize = SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + mVariableBufferPayloadSize;
mVariableBuffer = AllocateRuntimePool (mVariableBufferSize);
ASSERT (mVariableBuffer != NULL);
@ -924,13 +1018,13 @@ SmmVariableReady (
gRT->GetNextVariableName = RuntimeServiceGetNextVariableName;
gRT->SetVariable = RuntimeServiceSetVariable;
gRT->QueryVariableInfo = RuntimeServiceQueryVariableInfo;
//
// Install the Variable Architectural Protocol on a new handle.
//
Status = gBS->InstallProtocolInterface (
&mHandle,
&gEfiVariableArchProtocolGuid,
&gEfiVariableArchProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
@ -955,6 +1049,8 @@ SmmVariableReady (
NULL
);
ASSERT_EFI_ERROR (Status);
gBS->CloseEvent (Event);
}
@ -963,7 +1059,7 @@ SmmVariableReady (
@param[in] Event Event whose notification function is being invoked.
@param[in] Context Pointer to the notification function's context.
**/
VOID
EFIAPI
@ -982,26 +1078,28 @@ SmmVariableWriteReady (
if (EFI_ERROR (Status)) {
return;
}
Status = gBS->InstallProtocolInterface (
&mHandle,
&gEfiVariableWriteArchProtocolGuid,
&gEfiVariableWriteArchProtocolGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
ASSERT_EFI_ERROR (Status);
gBS->CloseEvent (Event);
}
/**
Variable Driver main entry point. The Variable driver places the 4 EFI
runtime services in the EFI System Table and installs arch protocols
runtime services in the EFI System Table and installs arch protocols
for variable read and write services being available. It also registers
a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS Variable service successfully initialized.
**/
@ -1024,10 +1122,10 @@ VariableSmmRuntimeInitialize (
// Smm variable service is ready
//
EfiCreateProtocolNotifyEvent (
&gEfiSmmVariableProtocolGuid,
TPL_CALLBACK,
SmmVariableReady,
NULL,
&gEfiSmmVariableProtocolGuid,
TPL_CALLBACK,
SmmVariableReady,
NULL,
&SmmVariableRegistration
);
@ -1035,10 +1133,10 @@ VariableSmmRuntimeInitialize (
// Smm Non-Volatile variable write service is ready
//
EfiCreateProtocolNotifyEvent (
&gSmmVariableWriteGuid,
TPL_CALLBACK,
SmmVariableWriteReady,
NULL,
&gSmmVariableWriteGuid,
TPL_CALLBACK,
SmmVariableWriteReady,
NULL,
&SmmVariableWriteRegistration
);
@ -1046,11 +1144,11 @@ VariableSmmRuntimeInitialize (
// Register the event to reclaim variable for OS usage.
//
EfiCreateEventReadyToBootEx (
TPL_NOTIFY,
OnReadyToBoot,
NULL,
TPL_NOTIFY,
OnReadyToBoot,
NULL,
&OnReadyToBootEvent
);
);
//
// Register the event to inform SMM variable that it is at runtime.
@ -1062,7 +1160,7 @@ VariableSmmRuntimeInitialize (
NULL,
&gEfiEventExitBootServicesGuid,
&ExitBootServiceEvent
);
);
//
// Register the event to inform SMM variable that it is at runtime for legacy boot.
@ -1086,7 +1184,7 @@ VariableSmmRuntimeInitialize (
&gEfiEventVirtualAddressChangeGuid,
&mVirtualAddressChangeEvent
);
return EFI_SUCCESS;
}

View File

@ -1,24 +1,25 @@
## @file
# This module is the Runtime DXE part correspond to SMM variable module.
# Runtime DXE part corresponding to SMM authenticated variable module.
#
# It installs variable arch protocol and variable write arch protocol to provide
# four EFI_RUNTIME_SERVICES: SetVariable, GetVariable, GetNextVariableName and QueryVariableInfo
# and works with SMM variable module together.
# This module installs variable arch protocol and variable write arch protocol to provide
# variable service. This module need work together with SMM authenticated variable module.
#
# Caution: This module requires additional review when modified.
# This driver will have external input - variable data.
# This external input must be validated carefully to avoid security issues such as
# buffer overflow or integer overflow.
# The whole SMM authentication variable design relies on the integrity of flash part and SMM.
# which is assumed to be protected by platform. All variable code and metadata in flash/SMM Memory
# may not be modified without authorization. If platform fails to protect these resources,
# the authentication service provided in this driver will be broken, and the behavior is undefined.
#
# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
@ -41,6 +42,7 @@
[Sources]
VariableSmmRuntimeDxe.c
Measurement.c
[Packages]
MdePkg/MdePkg.dec
@ -48,13 +50,13 @@
[LibraryClasses]
MemoryAllocationLib
BaseLib
BaseLib
UefiBootServicesTableLib
DebugLib
UefiRuntimeLib
DxeServicesTableLib
UefiDriverEntryPoint
PcdLib
TpmMeasurementLib
[Protocols]
gEfiVariableWriteArchProtocolGuid ## PRODUCES
@ -74,10 +76,15 @@
## CONSUMES ## GUID # Protocol notify
gSmmVariableWriteGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
## SOMETIMES_CONSUMES ## Variable:L"PK"
## SOMETIMES_CONSUMES ## Variable:L"KEK"
## SOMETIMES_CONSUMES ## Variable:L"SecureBoot"
gEfiGlobalVariableGuid
## SOMETIMES_CONSUMES ## Variable:L"DB"
## SOMETIMES_CONSUMES ## Variable:L"DBX"
gEfiImageSecurityDatabaseGuid
[Depex]
gEfiSmmCommunicationProtocolGuid