Revision: 14378
http://edk2.svn.sourceforge.net/edk2/?rev=14378&view=rev
Author: niruiyu
Date: 2013-05-20 07:10:10 +0000 (Mon, 20 May 2013)
Log Message:
-----------
Add the EDKII_VARIABLE_LOCK_PROTOCOL implementation in SecurityPkg variable
drivers.
Signed-off-by: Ruiyu Ni <[email protected]>
Reviewed-by: Star Zeng <[email protected]>
Modified Paths:
--------------
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
2013-05-20 07:04:56 UTC (rev 14377)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.c
2013-05-20 07:10:10 UTC (rev 14378)
@@ -35,14 +35,30 @@
///
/// Define a memory cache that improves the search performance for a variable.
///
-VARIABLE_STORE_HEADER *mNvVariableCache = NULL;
+VARIABLE_STORE_HEADER *mNvVariableCache = NULL;
///
/// The memory entry used for variable statistics data.
///
-VARIABLE_INFO_ENTRY *gVariableInfo = NULL;
+VARIABLE_INFO_ENTRY *gVariableInfo = NULL;
+///
+/// The list to store the variables which cannot be set after the
EFI_END_OF_DXE_EVENT_GROUP_GUID
+/// or EVT_GROUP_READY_TO_BOOT event.
+///
+LIST_ENTRY mLockedVariableList = INITIALIZE_LIST_HEAD_VARIABLE
(mLockedVariableList);
+///
+/// The flag to indicate whether the platform has left the DXE phase of
execution.
+///
+BOOLEAN mEndOfDxe = FALSE;
+
+///
+/// The flag to indicate whether the variable storage locking is enabled.
+///
+BOOLEAN mEnableLocking = TRUE;
+
+
/**
Routine used to track statistical information about variable usage.
The data is stored in the EFI system table so it can be accessed later.
@@ -2312,6 +2328,58 @@
}
/**
+ 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
+ )
+{
+ VARIABLE_ENTRY *Entry;
+
+ if (VariableName == NULL || VariableName[0] == 0 || VendorGuid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mEndOfDxe) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ Entry = AllocateRuntimePool (sizeof (*Entry) + StrSize (VariableName));
+ if (Entry == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DEBUG ((EFI_D_INFO, "[Variable] Lock: %g:%s\n", VendorGuid, VariableName));
+
+
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ Entry->Name = (CHAR16 *) (Entry + 1);
+ StrCpy (Entry->Name, VariableName);
+ CopyGuid (&Entry->Guid, VendorGuid);
+ InsertTailList (&mLockedVariableList, &Entry->Link);
+
+ ReleaseLockOnlyAtBootTime
(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
+
+ return EFI_SUCCESS;
+}
+
+/**
This code checks if variable should be treated as read-only variable.
@param[in] VariableName Name of the Variable.
@@ -2627,6 +2695,8 @@
VARIABLE_HEADER *NextVariable;
EFI_PHYSICAL_ADDRESS Point;
UINTN PayloadSize;
+ LIST_ENTRY *Link;
+ VARIABLE_ENTRY *Entry;
//
// Check input parameters.
@@ -2717,16 +2787,6 @@
}
}
- if (AtRuntime ()) {
- //
- // HwErrRecSupport Global Variable identifies the level of hardware error
record persistence
- // support implemented by the platform. This variable is only modified by
firmware and is read-only to the OS.
- //
- if (CompareGuid (VendorGuid, &gEfiGlobalVariableGuid) && (StrCmp
(VariableName, L"HwErrRecSupport") == 0)) {
- return EFI_WRITE_PROTECTED;
- }
- }
-
AcquireLockOnlyAtBootTime(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
//
@@ -2745,13 +2805,31 @@
mVariableModuleGlobal->NonVolatileLastVariableOffset = (UINTN)
NextVariable - (UINTN) Point;
}
+ if (mEndOfDxe && mEnableLocking) {
+ //
+ // Treat the variables listed in the forbidden variable list as read-only
after leaving DXE phase.
+ //
+ for ( Link = GetFirstNode (&mLockedVariableList)
+ ; !IsNull (&mLockedVariableList, Link)
+ ; Link = GetNextNode (&mLockedVariableList, Link)
+ ) {
+ Entry = BASE_CR (Link, VARIABLE_ENTRY, Link);
+ if (CompareGuid (&Entry->Guid, VendorGuid) && (StrCmp (Entry->Name,
VariableName) == 0)) {
+ Status = EFI_WRITE_PROTECTED;
+ DEBUG ((EFI_D_INFO, "[Variable]: Changing readonly variable after
leaving DXE phase - %g:%s\n", VendorGuid, VariableName));
+ goto Done;
+ }
+ }
+ }
+
//
// Check whether the input variable is already existed.
//
Status = FindVariable (VariableName, VendorGuid, &Variable,
&mVariableModuleGlobal->VariableGlobal, TRUE);
if (!EFI_ERROR (Status)) {
if (((Variable.CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) &&
AtRuntime ()) {
- return EFI_WRITE_PROTECTED;
+ Status = EFI_WRITE_PROTECTED;
+ goto Done;
}
}
@@ -2776,6 +2854,7 @@
Status = ProcessVariable (VariableName, VendorGuid, Data, DataSize,
&Variable, Attributes);
}
+Done:
InterlockedDecrement (&mVariableModuleGlobal->VariableGlobal.ReentrantState);
ReleaseLockOnlyAtBootTime
(&mVariableModuleGlobal->VariableGlobal.VariableServicesLock);
Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
2013-05-20 07:04:56 UTC (rev 14377)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/Variable.h
2013-05-20 07:10:10 UTC (rev 14378)
@@ -21,6 +21,7 @@
#include <Protocol/FaultTolerantWrite.h>
#include <Protocol/FirmwareVolumeBlock.h>
#include <Protocol/Variable.h>
+#include <Protocol/VariableLock.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/UefiDriverEntryPoint.h>
@@ -106,6 +107,12 @@
VOID *Data;
} VARIABLE_CACHE_ENTRY;
+typedef struct {
+ EFI_GUID Guid;
+ CHAR16 *Name;
+ LIST_ENTRY Link;
+} VARIABLE_ENTRY;
+
/**
Flush the HOB variable to flash.
@@ -577,7 +584,30 @@
OUT UINT64 *RemainingVariableStorageSize,
OUT UINT64 *MaximumVariableSize
);
-
+
+/**
+ 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
+ );
+
extern VARIABLE_MODULE_GLOBAL *mVariableModuleGlobal;
#endif
Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
2013-05-20 07:04:56 UTC (rev 14377)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableDxe.c
2013-05-20 07:10:10 UTC (rev 14378)
@@ -16,11 +16,13 @@
#include "Variable.h"
#include "AuthService.h"
-extern VARIABLE_STORE_HEADER *mNvVariableCache;
-extern VARIABLE_INFO_ENTRY *gVariableInfo;
-EFI_HANDLE mHandle = NULL;
-EFI_EVENT mVirtualAddressChangeEvent = NULL;
-EFI_EVENT mFtwRegistration = NULL;
+extern VARIABLE_STORE_HEADER *mNvVariableCache;
+extern VARIABLE_INFO_ENTRY *gVariableInfo;
+EFI_HANDLE mHandle = NULL;
+EFI_EVENT mVirtualAddressChangeEvent = NULL;
+EFI_EVENT mFtwRegistration = NULL;
+extern BOOLEAN mEndOfDxe;
+EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock = {
VariableLockRequestToLock };
/**
Return TRUE if ExitBootServices () has been called.
@@ -257,13 +259,35 @@
VOID *Context
)
{
+ //
+ // Set the End Of DXE bit in case the EFI_END_OF_DXE_EVENT_GROUP_GUID event
is not signaled.
+ //
+ mEndOfDxe = TRUE;
ReclaimForOS ();
if (FeaturePcdGet (PcdVariableCollectStatistics)) {
gBS->InstallConfigurationTable (&gEfiAuthenticatedVariableGuid,
gVariableInfo);
}
}
+/**
+ Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+ This is a notification function registered on
EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context.
+
+**/
+VOID
+EFIAPI
+OnEndOfDxe (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ mEndOfDxe = TRUE;
+}
+
/**
Fault Tolerant Write protocol notification event handler.
@@ -378,10 +402,19 @@
{
EFI_STATUS Status;
EFI_EVENT ReadyToBootEvent;
+ EFI_EVENT EndOfDxeEvent;
Status = VariableCommonInitialize ();
ASSERT_EFI_ERROR (Status);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVariableLockProtocolGuid,
+ &mVariableLock,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
SystemTable->RuntimeServices->GetVariable =
VariableServiceGetVariable;
SystemTable->RuntimeServices->GetNextVariableName =
VariableServiceGetNextVariableName;
SystemTable->RuntimeServices->SetVariable =
VariableServiceSetVariable;
@@ -428,7 +461,21 @@
NULL,
&ReadyToBootEvent
);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Register the event handling function to set the End Of DXE flag.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ OnEndOfDxe,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
return EFI_SUCCESS;
}
Modified:
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
===================================================================
---
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
2013-05-20 07:04:56 UTC (rev 14377)
+++
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableRuntimeDxe.inf
2013-05-20 07:10:10 UTC (rev 14378)
@@ -67,11 +67,12 @@
gEfiVariableWriteArchProtocolGuid ## ALWAYS_PRODUCES
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES
gEfiFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
+ gEdkiiVariableLockProtocolGuid ## ALWAYS_PRODUCES
[Guids]
gEfiAuthenticatedVariableGuid ## PRODUCES ## Configuration
Table Guid
gEfiGlobalVariableGuid ## PRODUCES ## Variable Guid
- gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
+ gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event
gEfiCertTypeRsa2048Sha256Guid
gEfiImageSecurityDatabaseGuid
gEfiCertX509Guid
@@ -82,6 +83,7 @@
gEfiSystemNvDataFvGuid ## CONSUMES
gEfiCertDbGuid
gEfiHardwareErrorVariableGuid ## SOMETIMES_CONSUMES
+ gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
Modified: trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
2013-05-20 07:04:56 UTC (rev 14377)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.c
2013-05-20 07:10:10 UTC (rev 14378)
@@ -29,6 +29,7 @@
#include <Protocol/SmmFirmwareVolumeBlock.h>
#include <Protocol/SmmFaultTolerantWrite.h>
#include <Protocol/SmmAccess2.h>
+#include <Protocol/SmmEndOfDxe.h>
#include <Library/SmmServicesTableLib.h>
@@ -46,15 +47,61 @@
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 @@
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 @@
break;
case SMM_VARIABLE_FUNCTION_READY_TO_BOOT:
+ mEndOfDxe = TRUE;
if (AtRuntime()) {
Status = EFI_UNSUPPORTED;
break;
@@ -673,6 +722,19 @@
*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,7 +745,29 @@
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 @@
VOID *SmmFtwRegistration;
EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
UINTN Size;
+ VOID *SmmEndOfDxeRegistration;
//
// Variable initialize.
@@ -849,6 +934,16 @@
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.
//
Status = gSmst->SmmRegisterProtocolNotify (
Modified:
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
===================================================================
--- trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
2013-05-20 07:04:56 UTC (rev 14377)
+++ trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmm.inf
2013-05-20 07:10:10 UTC (rev 14378)
@@ -73,6 +73,7 @@
gEfiSmmVariableProtocolGuid ## ALWAYS_PRODUCES
gEfiSmmFaultTolerantWriteProtocolGuid ## SOMETIMES_CONSUMES
gEfiSmmAccess2ProtocolGuid ## ALWAYS_CONSUMES
+ gEfiSmmEndOfDxeProtocolGuid ## ALWAYS_CONSUMES
[Guids]
gEfiAuthenticatedVariableGuid ## PRODUCES ## Configuration
Table Guid
Modified:
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
===================================================================
---
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
2013-05-20 07:04:56 UTC (rev 14377)
+++
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.c
2013-05-20 07:10:10 UTC (rev 14378)
@@ -29,6 +29,7 @@
#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 @@
UINTN mVariableBufferSize;
UINTN mVariableBufferPayloadSize;
EFI_LOCK mVariableServicesLock;
+EDKII_VARIABLE_LOCK_PROTOCOL mVariableLock;
/**
Acquires lock only at boot time. Simply returns at runtime.
@@ -173,7 +175,74 @@
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 @@
IN EFI_SYSTEM_TABLE *SystemTable
)
{
+ EFI_STATUS Status;
VOID *SmmVariableRegistration;
VOID *SmmVariableWriteRegistration;
EFI_EVENT OnReadyToBootEvent;
@@ -747,6 +817,15 @@
EfiInitializeLock (&mVariableServicesLock, TPL_NOTIFY);
+ mVariableLock.RequestToLock = VariableLockRequestToLock;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiVariableLockProtocolGuid,
+ &mVariableLock,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
//
// Smm variable service is ready
//
Modified:
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
===================================================================
---
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
2013-05-20 07:04:56 UTC (rev 14377)
+++
trunk/edk2/SecurityPkg/VariableAuthenticated/RuntimeDxe/VariableSmmRuntimeDxe.inf
2013-05-20 07:10:10 UTC (rev 14378)
@@ -59,6 +59,7 @@
gEfiVariableArchProtocolGuid ## ALWAYS_PRODUCES
gEfiSmmCommunicationProtocolGuid
gEfiSmmVariableProtocolGuid
+ gEdkiiVariableLockProtocolGuid ## ALWAYS_PRODUCES
[Guids]
gEfiEventVirtualAddressChangeGuid ## PRODUCES ## Event
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits