summaryrefslogtreecommitdiff
path: root/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
diff options
context:
space:
mode:
authorniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>2013-05-20 07:10:10 +0000
committerniruiyu <niruiyu@6f19259b-4bc3-4df7-8a09-765794883524>2013-05-20 07:10:10 +0000
commit6ab9f44138c62cea69000e7ada2161c07efadf93 (patch)
tree68d28976bed937580e45a0b5bbdbc339cb7c6570 /SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
parent51547bb879f66d3b4e46d69c112047d39dc234cc (diff)
downloadedk2-platforms-6ab9f44138c62cea69000e7ada2161c07efadf93.tar.xz
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
Diffstat (limited to 'SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c')
-rw-r--r--SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
index b7c7f4ffb7..7011343872 100644
--- a/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
+++ b/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
@@ -29,6 +29,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/Variable.h>
#include <Protocol/SmmCommunication.h>
#include <Protocol/SmmVariable.h>
+#include <Protocol/VariableLock.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
@@ -54,6 +55,7 @@ UINT8 *mVariableBufferPhysical = NULL;
UINTN mVariableBufferSize;
UINTN mVariableBufferPayloadSize;
EFI_LOCK mVariableServicesLock;
+EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock;
/**
Acquires lock only at boot time. Simply returns at runtime.
@@ -173,6 +175,73 @@ SendCommunicateBuffer (
return SmmVariableFunctionHeader->ReturnStatus;
}
+/**
+ Mark a variable that will become read-only after leaving the DXE phase of execution.
+
+ @param[in] This The VARIABLE_LOCK_PROTOCOL instance.
+ @param[in] VariableName A pointer to the variable name that will be made read-only subsequently.
+ @param[in] VendorGuid A pointer to the vendor GUID that will be made read-only subsequently.
+
+ @retval EFI_SUCCESS The variable specified by the VariableName and the VendorGuid was marked
+ as pending to be read-only.
+ @retval EFI_INVALID_PARAMETER VariableName or VendorGuid is NULL.
+ Or VariableName is an empty string.
+ @retval EFI_ACCESS_DENIED EFI_END_OF_DXE_EVENT_GROUP_GUID or EFI_EVENT_GROUP_READY_TO_BOOT has
+ already been signaled.
+ @retval EFI_OUT_OF_RESOURCES There is not enough resource to hold the lock request.
+**/
+EFI_STATUS
+EFIAPI
+VariableLockRequestToLock (
+ IN CONST EDKII_VARIABLE_LOCK_PROTOCOL *This,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ )
+{
+ EFI_STATUS Status;
+ UINTN VariableNameSize;
+ UINTN PayloadSize;
+ SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE *VariableToLock;
+
+ if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ VariableNameSize = StrSize (VariableName);
+
+ //
+ // If VariableName exceeds SMM payload limit. Return failure
+ //
+ if (VariableNameSize > mVariableBufferPayloadSize - OFFSET_OF (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AcquireLockOnlyAtBootTime(&mVariableServicesLock);
+
+ //
+ // Init the communicate buffer. The buffer data size is:
+ // SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + PayloadSize.
+ //
+ PayloadSize = OFFSET_OF (SMM_VARIABLE_COMMUNICATE_LOCK_VARIABLE, Name) + VariableNameSize;
+ Status = InitCommunicateBuffer ((VOID **) &VariableToLock, PayloadSize, SMM_VARIABLE_FUNCTION_LOCK_VARIABLE);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (VariableToLock != NULL);
+
+ CopyGuid (&VariableToLock->Guid, VendorGuid);
+ VariableToLock->NameSize = VariableNameSize;
+ CopyMem (VariableToLock->Name, VariableName, VariableToLock->NameSize);
+
+ //
+ // Send data to SMM.
+ //
+ Status = SendCommunicateBuffer (PayloadSize);
+
+Done:
+ ReleaseLockOnlyAtBootTime (&mVariableServicesLock);
+ return Status;
+}
/**
This code finds variable in storage blocks (Volatile or Non-Volatile).
@@ -740,6 +809,7 @@ VariableSmmRuntimeInitialize (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
+ EFI_STATUS Status;
VOID *SmmVariableRegistration;
VOID *SmmVariableWriteRegistration;
EFI_EVENT OnReadyToBootEvent;
@@ -747,6 +817,15 @@ VariableSmmRuntimeInitialize (
EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
+ mVariableLock.RequestToLock = VariableLockRequestToLock;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVariableLockProtocolGuid,
+ &mVariableLock,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Smm variable service is ready
//