17#include <Protocol/VariablePolicy.h>
20#include <Guid/VarCheckPolicyMmi.h>
27VOID *mMmCommunicationBuffer;
28UINTN mMmCommunicationBufferSize;
42InternalMmCommunicate (
43 IN OUT VOID *CommBuffer,
49 if ((CommBuffer ==
NULL) || (CommSize ==
NULL)) {
50 return EFI_INVALID_PARAMETER;
53 Status = mMmCommunication->Communicate (mMmCommunication, CommBuffer, CommBuffer, CommSize);
70ProtocolDisableVariablePolicy (
81 if (!
PcdGetBool (PcdAllowVariablePolicyEnforcementDisable)) {
82 return EFI_WRITE_PROTECTED;
88 BufferSize = mMmCommunicationBufferSize;
89 CommHeader = mMmCommunicationBuffer;
93 PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
94 PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
95 PolicyHeader->Command = VAR_CHECK_POLICY_COMMAND_DISABLE;
97 Status = InternalMmCommunicate (CommHeader, &BufferSize);
98 DEBUG ((DEBUG_VERBOSE,
"%a - MmCommunication returned %r.\n", __func__, Status));
102 return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
130 return EFI_INVALID_PARAMETER;
136 BufferSize = mMmCommunicationBufferSize;
137 CommHeader = mMmCommunicationBuffer;
142 PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
143 PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
144 PolicyHeader->Command = VAR_CHECK_POLICY_COMMAND_IS_ENABLED;
146 Status = InternalMmCommunicate (CommHeader, &BufferSize);
147 DEBUG ((DEBUG_VERBOSE,
"%a - MmCommunication returned %r.\n", __func__, Status));
149 if (!EFI_ERROR (Status)) {
150 Status = PolicyHeader->Result;
151 *State = CommandParams->State;
177ProtocolRegisterVariablePolicy (
188 if (NewPolicy ==
NULL) {
189 return EFI_INVALID_PARAMETER;
195 Status =
SafeUintnAdd (RequiredSize, NewPolicy->Size, &RequiredSize);
196 if (EFI_ERROR (Status) || (RequiredSize > mMmCommunicationBufferSize)) {
199 "%a - Policy too large for buffer! %r, %d > %d \n",
203 mMmCommunicationBufferSize
205 return EFI_OUT_OF_RESOURCES;
211 BufferSize = mMmCommunicationBufferSize;
212 CommHeader = mMmCommunicationBuffer;
214 PolicyBuffer = (VOID *)(PolicyHeader + 1);
217 PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
218 PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
219 PolicyHeader->Command = VAR_CHECK_POLICY_COMMAND_REGISTER;
222 CopyMem (PolicyBuffer, NewPolicy, NewPolicy->Size);
224 Status = InternalMmCommunicate (CommHeader, &BufferSize);
225 DEBUG ((DEBUG_VERBOSE,
"%a - MmCommunication returned %r.\n", __func__, Status));
229 return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
249DumpVariablePolicyHelper (
250 IN UINT32 PageRequested,
251 OUT UINT32 *TotalSize,
252 OUT UINT32 *PageSize,
253 OUT BOOLEAN *HasMore,
263 if ((TotalSize ==
NULL) || (PageSize ==
NULL) || (HasMore ==
NULL) || (Buffer ==
NULL)) {
264 return EFI_INVALID_PARAMETER;
268 BufferSize = mMmCommunicationBufferSize;
269 CommHeader = mMmCommunicationBuffer;
274 PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
275 PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
276 PolicyHeader->Command = VAR_CHECK_POLICY_COMMAND_DUMP;
278 CommandParams->PageRequested = PageRequested;
280 Status = InternalMmCommunicate (CommHeader, &BufferSize);
281 DEBUG ((DEBUG_VERBOSE,
"%a - MmCommunication returned %r.\n", __func__, Status));
283 if (!EFI_ERROR (Status)) {
284 Status = PolicyHeader->Result;
285 *TotalSize = CommandParams->TotalSize;
286 *PageSize = CommandParams->PageSize;
287 *HasMore = CommandParams->HasMore;
288 *Buffer = (UINT8 *)(CommandParams + 1);
312ProtocolDumpVariablePolicy (
313 OUT UINT8 *Policy OPTIONAL,
325 if ((Size ==
NULL) || ((*Size > 0) && (Policy ==
NULL))) {
326 return EFI_INVALID_PARAMETER;
338 Status = DumpVariablePolicyHelper (0, &PolicySize, &PageSize, &HasMore, &Source);
339 if (EFI_ERROR (Status)) {
344 if (*Size < PolicySize) {
346 Status = EFI_BUFFER_TOO_SMALL;
353 Destination = Policy;
356 for (PageIndex = 1; !EFI_ERROR (Status) && HasMore && PageIndex < MAX_UINT32; PageIndex++) {
357 Status = DumpVariablePolicyHelper (PageIndex, &PolicySize, &PageSize, &HasMore, &Source);
358 if (!EFI_ERROR (Status)) {
359 CopyMem (Destination, Source, PageSize);
360 Destination += PageSize;
365 }
while (Status == EFI_TIMEOUT);
384ProtocolLockVariablePolicy (
396 BufferSize = mMmCommunicationBufferSize;
397 CommHeader = mMmCommunicationBuffer;
401 PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
402 PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
403 PolicyHeader->Command = VAR_CHECK_POLICY_COMMAND_LOCK;
405 Status = InternalMmCommunicate (CommHeader, &BufferSize);
406 DEBUG ((DEBUG_VERBOSE,
"%a - MmCommunication returned %r.\n", __func__, Status));
410 return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
462InternalProtocolGetVariablePolicyInfo (
466 IN OUT UINTN *VariablePolicyVariableNameBufferSize, OPTIONAL
467 OUT VOID *VariablePolicy,
468 OUT CHAR16 *VariablePolicyVariableName OPTIONAL
472 CHAR16 *OutputVariableName;
476 UINTN AllowedOutputVariableNameSize;
478 UINTN VariableNameSize;
480 if ((VariableName ==
NULL) || (VendorGuid ==
NULL) || (VariablePolicy ==
NULL)) {
481 return EFI_INVALID_PARAMETER;
485 case VAR_CHECK_POLICY_COMMAND_GET_INFO:
486 case VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO:
489 return EFI_INVALID_PARAMETER;
496 (VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE - VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END)
498 if (VariableNameSize >= (VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE - VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END)) {
499 Status = EFI_INVALID_PARAMETER;
503 if ((VariablePolicyVariableName !=
NULL) && (VariablePolicyVariableNameBufferSize ==
NULL)) {
504 return EFI_INVALID_PARAMETER;
508 BufferSize = mMmCommunicationBufferSize;
509 CommHeader = mMmCommunicationBuffer;
512 VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE,
514 &AllowedOutputVariableNameSize
516 if (EFI_ERROR (Status)) {
517 Status = EFI_INVALID_PARAMETER;
521 if (VariablePolicyVariableNameBufferSize !=
NULL) {
522 AllowedOutputVariableNameSize =
MIN (AllowedOutputVariableNameSize, *VariablePolicyVariableNameBufferSize);
524 AllowedOutputVariableNameSize = 0;
532 PolicyHeader->Signature = VAR_CHECK_POLICY_COMM_SIG;
533 PolicyHeader->Revision = VAR_CHECK_POLICY_COMM_REVISION;
534 PolicyHeader->Command = Command;
536 ZeroMem ((VOID *)&CommandParams->OutputPolicyEntry, sizeof (CommandParams->OutputPolicyEntry));
537 CopyGuid (&CommandParams->InputVendorGuid, VendorGuid);
538 Status =
SafeUintnToUint32 (VariableNameSize, &CommandParams->InputVariableNameSize);
539 if (EFI_ERROR (Status)) {
540 Status = EFI_INVALID_PARAMETER;
544 Status =
SafeUintnToUint32 (AllowedOutputVariableNameSize, &CommandParams->OutputVariableNameSize);
545 if (EFI_ERROR (Status)) {
546 Status = EFI_INVALID_PARAMETER;
550 if (AllowedOutputVariableNameSize > 0) {
552 CommandParams->InputVariableName,
553 AllowedOutputVariableNameSize / sizeof (CHAR16),
555 (
UINTN)CommandParams->InputVariableNameSize / sizeof (CHAR16)
560 Status = InternalMmCommunicate (CommHeader, &BufferSize);
564 (VOID *)&CommandParams->OutputPolicyEntry,
565 (Command == VAR_CHECK_POLICY_COMMAND_GET_INFO) ?
566 sizeof (CommandParams->OutputPolicyEntry.VariablePolicy) :
567 sizeof (CommandParams->OutputPolicyEntry.LockOnVarStatePolicy)
570 if (VariablePolicyVariableNameBufferSize ==
NULL) {
571 if (VariablePolicyVariableName !=
NULL) {
572 Status = EFI_INVALID_PARAMETER;
578 if (PolicyHeader->Result == EFI_BUFFER_TOO_SMALL) {
579 *VariablePolicyVariableNameBufferSize = (
UINTN)CommandParams->OutputVariableNameSize;
584 if (CommandParams->OutputVariableNameSize > 0) {
586 ((
UINTN)CommandParams + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
587 (
UINTN)CommandParams->InputVariableNameSize,
588 (
UINTN *)&OutputVariableName
590 if (EFI_ERROR (Status)) {
591 Status = EFI_BAD_BUFFER_SIZE;
596 VariablePolicyVariableName,
597 *VariablePolicyVariableNameBufferSize /
sizeof (CHAR16),
599 (
UINTN)CommandParams->OutputVariableNameSize
602 *VariablePolicyVariableNameBufferSize = (
UINTN)CommandParams->OutputVariableNameSize;
605 *VariablePolicyVariableNameBufferSize = 0;
613 return (EFI_ERROR (Status)) ? Status : PolicyHeader->Result;
661ProtocolGetVariablePolicyInfo (
664 IN OUT UINTN *VariablePolicyVariableNameBufferSize, OPTIONAL
666 OUT CHAR16 *VariablePolicyVariableName OPTIONAL
669 return InternalProtocolGetVariablePolicyInfo (
670 VAR_CHECK_POLICY_COMMAND_GET_INFO,
673 VariablePolicyVariableNameBufferSize,
675 VariablePolicyVariableName
727ProtocolGetLockOnVariableStateVariablePolicyInfo (
730 IN OUT UINTN *VariableLockPolicyVariableNameBufferSize, OPTIONAL
732 OUT CHAR16 *VariableLockPolicyVariableName OPTIONAL
735 return InternalProtocolGetVariablePolicyInfo (
736 VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO,
739 VariableLockPolicyVariableNameBufferSize,
741 VariableLockPolicyVariableName
759InitMmCommonCommBuffer (
761 OUT VOID **LocatedBuffer
769 if ((BufferSize ==
NULL) || (LocatedBuffer ==
NULL)) {
770 return EFI_INVALID_PARAMETER;
775 if (*LocatedBuffer ==
NULL) {
776 Status = EFI_OUT_OF_RESOURCES;
795VariablePolicyVirtualAddressCallback (
816VariablePolicySmmDxeMain (
822 BOOLEAN ProtocolInstalled;
823 BOOLEAN VirtualAddressChangeRegistered;
827 ProtocolInstalled =
FALSE;
828 VirtualAddressChangeRegistered =
FALSE;
831 mMmCommunicationBufferSize = VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE;
833 Status = InitMmCommonCommBuffer (&mMmCommunicationBufferSize, &mMmCommunicationBuffer);
834 if (EFI_ERROR (Status)) {
835 DEBUG ((DEBUG_ERROR,
"%a - Failed to locate a viable MM comm buffer! %r\n", __func__, Status));
841 Status =
gBS->LocateProtocol (&gEfiMmCommunication2ProtocolGuid,
NULL, (VOID **)&mMmCommunication);
842 if (EFI_ERROR (Status)) {
843 DEBUG ((DEBUG_ERROR,
"%a - Failed to locate MmCommunication protocol! %r\n", __func__, Status));
849 mVariablePolicyProtocol.Revision = EDKII_VARIABLE_POLICY_PROTOCOL_REVISION;
850 mVariablePolicyProtocol.DisableVariablePolicy = ProtocolDisableVariablePolicy;
852 mVariablePolicyProtocol.RegisterVariablePolicy = ProtocolRegisterVariablePolicy;
853 mVariablePolicyProtocol.DumpVariablePolicy = ProtocolDumpVariablePolicy;
854 mVariablePolicyProtocol.LockVariablePolicy = ProtocolLockVariablePolicy;
855 mVariablePolicyProtocol.GetVariablePolicyInfo = ProtocolGetVariablePolicyInfo;
856 mVariablePolicyProtocol.GetLockOnVariableStateVariablePolicyInfo = ProtocolGetLockOnVariableStateVariablePolicyInfo;
859 Status =
gBS->InstallMultipleProtocolInterfaces (
861 &gEdkiiVariablePolicyProtocolGuid,
862 &mVariablePolicyProtocol,
865 if (EFI_ERROR (Status)) {
866 DEBUG ((DEBUG_ERROR,
"%a - Failed to install protocol! %r\n", __func__, Status));
869 ProtocolInstalled =
TRUE;
879 Status =
gBS->CreateEventEx (
882 VariablePolicyVirtualAddressCallback,
884 &gEfiEventVirtualAddressChangeGuid,
885 &VirtualAddressChangeEvent
887 if (EFI_ERROR (Status)) {
888 DEBUG ((DEBUG_ERROR,
"%a - Failed to create VirtualAddressChange event! %r\n", __func__, Status));
891 VirtualAddressChangeRegistered =
TRUE;
898 if (EFI_ERROR (Status)) {
899 if (ProtocolInstalled) {
900 gBS->UninstallProtocolInterface (&ImageHandle, &gEdkiiVariablePolicyProtocolGuid, &mVariablePolicyProtocol);
903 if (VirtualAddressChangeRegistered) {
904 gBS->CloseEvent (VirtualAddressChangeEvent);
UINTN EFIAPI StrnSizeS(IN CONST CHAR16 *String, IN UINTN MaxSize)
RETURN_STATUS EFIAPI StrnCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateRuntimePool(IN UINTN AllocationSize)
VOID ReleaseLockOnlyAtBootTime(IN EFI_LOCK *Lock)
VOID AcquireLockOnlyAtBootTime(IN EFI_LOCK *Lock)
#define OFFSET_OF(TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define PcdGetBool(TokenName)
RETURN_STATUS EFIAPI SafeUintnAdd(IN UINTN Augend, IN UINTN Addend, OUT UINTN *Result)
RETURN_STATUS EFIAPI SafeUintnToUint32(IN UINTN Operand, OUT UINT32 *Result)
RETURN_STATUS EFIAPI SafeUintnSub(IN UINTN Minuend, IN UINTN Subtrahend, OUT UINTN *Result)
VOID EFIAPI Exit(IN EFI_STATUS Status)
EFI_LOCK *EFIAPI EfiInitializeLock(IN OUT EFI_LOCK *Lock, IN EFI_TPL Priority)
EFI_STATUS EFIAPI EfiConvertPointer(IN UINTN DebugDisposition, IN OUT VOID **Address)
EFI_STATUS EFIAPI ProtocolIsVariablePolicyEnabled(OUT BOOLEAN *State)