Add the EDKII_VARIABLE_LOCK_PROTOCOL implementation in SecurityPkg variable drivers.

Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14378 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
niruiyu
2013-05-20 07:10:10 +00:00
parent 51547bb879
commit 6ab9f44138
8 changed files with 356 additions and 22 deletions

View File

@@ -29,6 +29,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmFirmwareVolumeBlock.h>
#include <Protocol/SmmFaultTolerantWrite.h>
#include <Protocol/SmmAccess2.h>
#include <Protocol/SmmEndOfDxe.h>
#include <Library/SmmServicesTableLib.h>
@@ -46,15 +47,61 @@ BOOLEAN mAtRuntime = F
EFI_GUID mZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
UINT8 *mVariableBufferPayload = NULL;
UINTN mVariableBufferPayloadSize;
extern BOOLEAN mEndOfDxe;
extern BOOLEAN mEnableLocking;
/**
This code sets variable in storage blocks (Volatile or Non-Volatile).
@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 Set successfully.
@return EFI_OUT_OF_RESOURCES Resource not enough to set variable.
@return EFI_NOT_FOUND Not found.
@return EFI_WRITE_PROTECTED Variable is read-only.
**/
EFI_STATUS
EFIAPI
SmmVariableSetVariable (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
)
{
EFI_STATUS Status;
//
// Disable write protection when the calling SetVariable() through EFI_SMM_VARIABLE_PROTOCOL.
//
mEnableLocking = FALSE;
Status = VariableServiceSetVariable (
VariableName,
VendorGuid,
Attributes,
DataSize,
Data
);
mEnableLocking = TRUE;
return Status;
}
EFI_SMM_VARIABLE_PROTOCOL gSmmVariable = {
VariableServiceGetVariable,
VariableServiceGetNextVariableName,
VariableServiceSetVariable,
SmmVariableSetVariable,
VariableServiceQueryVariableInfo
};
/**
Return TRUE if ExitBootServices () has been called.
@@ -455,6 +502,7 @@ SmmVariableHandler (
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *GetNextVariableName;
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO *QueryVariableInfo;
VARIABLE_INFO_ENTRY *VariableInfo;
SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock;
UINTN InfoSize;
UINTN NameBufferSize;
UINTN CommBufferPayloadSize;
@@ -641,6 +689,7 @@ SmmVariableHandler (
break;
case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
mEndOfDxe = TRUE;
if (AtRuntime()) {
Status = EFI_UNSUPPORTED;
break;
@@ -673,6 +722,19 @@ SmmVariableHandler (
*CommBufferSize = InfoSize + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE;
break;
case SMM_VARIABLE_FUNCTION_LOCK_VARIABLE:
if (mEndOfDxe) {
Status = EFI_ACCESS_DENIED;
} else {
VariableToLock = (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *) SmmVariableFunctionHeader->Data;
Status = VariableLockRequestToLock (
NULL,
VariableToLock->Name,
&VariableToLock->Guid
);
}
break;
default:
Status = EFI_UNSUPPORTED;
}
@@ -683,6 +745,28 @@ EXIT:
return EFI_SUCCESS;
}
/**
SMM END_OF_DXE protocol notification event handler.
@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 SmmEndOfDxeCallback runs successfully
**/
EFI_STATUS
EFIAPI
SmmEndOfDxeCallback (
IN CONST EFI_GUID *Protocol,
IN VOID *Interface,
IN EFI_HANDLE Handle
)
{
DEBUG ((EFI_D_INFO, "[Variable]END_OF_DXE is signaled\n"));
mEndOfDxe = TRUE;
return EFI_SUCCESS;
}
/**
SMM Fault Tolerant Write protocol notification event handler.
@@ -779,6 +863,7 @@ VariableServiceInitialize (
VOID *SmmFtwRegistration;
EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
UINTN Size;
VOID *SmmEndOfDxeRegistration;
//
// Variable initialize.
@@ -848,6 +933,16 @@ VariableServiceInitialize (
);
ASSERT_EFI_ERROR (Status);
//
// Register EFI_SMM_END_OF_DXE_PROTOCOL_GUID notify function.
//
Status = gSmst->SmmRegisterProtocolNotify (
&gEfiSmmEndOfDxeProtocolGuid,
SmmEndOfDxeCallback,
&SmmEndOfDxeRegistration
);
ASSERT_EFI_ERROR (Status);
//
// Register FtwNotificationEvent () notify function.
//