21#include <Protocol/VariablePolicy.h>
22#include <Library/VariablePolicyLib.h>
24#include <Guid/VarCheckPolicyMmi.h>
26#include "VarCheckPolicyLib.h"
35VariableServiceGetVariable (
36 IN CHAR16 *VariableName,
38 OUT UINT32 *Attributes OPTIONAL,
43UINT8 mSecurityEvalBuffer[VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE];
46UINT8 *mPaginationCache =
NULL;
47UINTN mPaginationCacheSize = 0;
48UINT32 mCurrentPaginationCommand = 0;
69VarCheckPolicyLibMmiHandler (
72 IN OUT VOID *CommBuffer,
76 UINTN InternalCommBufferSize;
77 VOID *InternalCommBuffer;
87 CHAR16 *InternalCopyOfOutputVariableName;
88 CHAR16 *ExternalCopyOfOutputVariableName;
89 UINT8 *DumpInputBuffer;
90 UINT8 *DumpOutputBuffer;
91 UINTN AllowedOutputVariableNameSize;
104 if ((CommBuffer ==
NULL) || (CommBufferSize ==
NULL)) {
105 DEBUG ((DEBUG_INFO,
"%a - Invalid comm buffer pointers!\n", __func__));
106 return EFI_INVALID_PARAMETER;
113 InternalCommBufferSize = *CommBufferSize;
114 if ((InternalCommBufferSize > VAR_CHECK_POLICY_MM_COMM_BUFFER_SIZE) ||
115 !VarCheckPolicyIsPrimaryBufferValid ((
UINTN)CommBuffer, (UINT64)InternalCommBufferSize))
117 DEBUG ((DEBUG_ERROR,
"%a - Invalid Primary Buffer (CommBuffer) supplied! 0x%016lX[0x%016lX]\n", __func__, CommBuffer, InternalCommBufferSize));
118 return EFI_INVALID_PARAMETER;
123 if (InternalCommBufferSize < ExpectedSize) {
124 DEBUG ((DEBUG_INFO,
"%a - Bad comm buffer size! %d < %d\n", __func__, InternalCommBufferSize, ExpectedSize));
125 return EFI_INVALID_PARAMETER;
132 InternalCommBuffer = &mSecurityEvalBuffer[0];
133 CopyMem (InternalCommBuffer, CommBuffer, InternalCommBufferSize);
134 PolicyCommHeader = CommBuffer;
135 InternalPolicyCommHeader = InternalCommBuffer;
137 if ((InternalPolicyCommHeader->Signature != VAR_CHECK_POLICY_COMM_SIG) ||
138 (InternalPolicyCommHeader->Revision != VAR_CHECK_POLICY_COMM_REVISION))
140 DEBUG ((DEBUG_INFO,
"%a - Signature or revision are incorrect!\n", __func__));
142 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
148 if ((mPaginationCache !=
NULL) && (InternalPolicyCommHeader->Command != mCurrentPaginationCommand)) {
150 mPaginationCache =
NULL;
151 mPaginationCacheSize = 0;
152 mCurrentPaginationCommand = 0;
158 PolicyCommHeader->Result = EFI_ABORTED;
159 switch (InternalPolicyCommHeader->Command) {
160 case VAR_CHECK_POLICY_COMMAND_DISABLE:
161 PolicyCommHeader->Result = DisableVariablePolicy ();
164 case VAR_CHECK_POLICY_COMMAND_IS_ENABLED:
168 if (InternalCommBufferSize < ExpectedSize) {
169 DEBUG ((DEBUG_INFO,
"%a - Bad comm buffer size! %d < %d\n", __func__, InternalCommBufferSize, ExpectedSize));
170 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
176 IsEnabledParams->State = IsVariablePolicyEnabled ();
180 case VAR_CHECK_POLICY_COMMAND_REGISTER:
184 if (InternalCommBufferSize < ExpectedSize) {
185 DEBUG ((DEBUG_INFO,
"%a - Bad comm buffer size! %d < %d\n", __func__, InternalCommBufferSize, ExpectedSize));
186 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
193 if ((PolicyEntry->Version != VARIABLE_POLICY_ENTRY_REVISION) ||
196 (InternalCommBufferSize < ExpectedSize))
198 DEBUG ((DEBUG_INFO,
"%a - Bad policy entry contents!\n", __func__));
199 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
203 PolicyCommHeader->Result = RegisterVariablePolicy (PolicyEntry);
206 case VAR_CHECK_POLICY_COMMAND_DUMP:
210 if (InternalCommBufferSize < ExpectedSize) {
211 DEBUG ((DEBUG_INFO,
"%a - Bad comm buffer size! %d < %d\n", __func__, InternalCommBufferSize, ExpectedSize));
212 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
221 if (DumpParamsIn->PageRequested == 0) {
222 if (mPaginationCache !=
NULL) {
224 mPaginationCache =
NULL;
228 DumpParamsOut->TotalSize = 0;
229 DumpParamsOut->PageSize = 0;
230 DumpParamsOut->HasMore =
FALSE;
232 SubCommandStatus = DumpVariablePolicy (
NULL, &TempSize);
233 if ((SubCommandStatus == EFI_BUFFER_TOO_SMALL) && (TempSize > 0)) {
234 mCurrentPaginationCommand = VAR_CHECK_POLICY_COMMAND_DUMP;
235 mPaginationCacheSize = TempSize;
236 DumpParamsOut->TotalSize = TempSize;
238 if (mPaginationCache ==
NULL) {
239 SubCommandStatus = EFI_OUT_OF_RESOURCES;
244 if (mPaginationCache !=
NULL) {
245 SubCommandStatus = DumpVariablePolicy (mPaginationCache, &TempSize);
249 if (!EFI_ERROR (SubCommandStatus) && (mPaginationCache !=
NULL)) {
250 DumpParamsOut->HasMore =
TRUE;
252 }
else if (mPaginationCache !=
NULL) {
253 DumpParamsOut->TotalSize = (UINT32)mPaginationCacheSize;
254 DumpOutputBuffer = (UINT8 *)(DumpParamsOut + 1);
257 DumpTotalPages = mPaginationCacheSize / VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;
258 if (mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE != 0) {
262 if (DumpParamsIn->PageRequested > DumpTotalPages) {
263 SubCommandStatus = EFI_INVALID_PARAMETER;
267 DumpInputBuffer = &mPaginationCache[VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE * (DumpParamsIn->PageRequested - 1)];
268 TempSize = VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;
270 if (DumpParamsIn->PageRequested == DumpTotalPages) {
271 TempSize = mPaginationCacheSize % VAR_CHECK_POLICY_MM_DUMP_BUFFER_SIZE;
274 CopyMem (DumpOutputBuffer, DumpInputBuffer, TempSize);
275 DumpParamsOut->PageSize = TempSize;
277 if (DumpParamsIn->PageRequested == DumpTotalPages) {
278 DumpParamsOut->HasMore =
FALSE;
280 mPaginationCache =
NULL;
281 mPaginationCacheSize = 0;
282 mCurrentPaginationCommand = 0;
285 DumpParamsOut->HasMore =
TRUE;
294 DumpParamsOut->TotalSize = 0;
295 DumpParamsOut->PageSize = 0;
296 DumpParamsOut->HasMore =
FALSE;
297 SubCommandStatus = EFI_TIMEOUT;
301 PolicyCommHeader->Result = SubCommandStatus;
304 case VAR_CHECK_POLICY_COMMAND_LOCK:
305 PolicyCommHeader->Result = LockVariablePolicy ();
308 case VAR_CHECK_POLICY_COMMAND_GET_INFO:
309 case VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO:
310 ExpectedSize += VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END + VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE;
312 if (InternalCommBufferSize < ExpectedSize) {
313 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
321 VAR_CHECK_POLICY_MM_GET_INFO_BUFFER_SIZE,
322 GetInfoParamsInternal->InputVariableNameSize,
323 &AllowedOutputVariableNameSize
325 if (EFI_ERROR (SubCommandStatus)) {
326 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
330 if (GetInfoParamsInternal->OutputVariableNameSize > 0) {
332 ((
UINTN)GetInfoParamsInternal + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
333 (
UINTN)GetInfoParamsInternal->InputVariableNameSize,
334 (
UINTN *)&InternalCopyOfOutputVariableName
336 if (EFI_ERROR (SubCommandStatus)) {
337 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
341 InternalCopyOfOutputVariableName =
NULL;
344 ZeroMem (&GetInfoParamsInternal->OutputPolicyEntry, sizeof (GetInfoParamsInternal->OutputPolicyEntry));
345 ZeroMem (&GetInfoParamsExternal->OutputPolicyEntry, sizeof (GetInfoParamsExternal->OutputPolicyEntry));
347 LocalSize = (
UINTN)GetInfoParamsInternal->OutputVariableNameSize;
349 if (InternalPolicyCommHeader->Command == VAR_CHECK_POLICY_COMMAND_GET_INFO) {
350 SubCommandStatus = GetVariablePolicyInfo (
351 GetInfoParamsInternal->InputVariableName,
352 &GetInfoParamsInternal->InputVendorGuid,
354 &GetInfoParamsInternal->OutputPolicyEntry.VariablePolicy,
355 InternalCopyOfOutputVariableName
357 }
else if (InternalPolicyCommHeader->Command == VAR_CHECK_POLICY_COMMAND_GET_LOCK_VAR_STATE_INFO) {
358 SubCommandStatus = GetLockOnVariableStateVariablePolicyInfo (
359 GetInfoParamsInternal->InputVariableName,
360 &GetInfoParamsInternal->InputVendorGuid,
362 &GetInfoParamsInternal->OutputPolicyEntry.LockOnVarStatePolicy,
363 InternalCopyOfOutputVariableName
366 PolicyCommHeader->Result = EFI_INVALID_PARAMETER;
370 if (EFI_ERROR (SubCommandStatus) && (SubCommandStatus != EFI_BUFFER_TOO_SMALL)) {
371 PolicyCommHeader->Result = SubCommandStatus;
375 if (EFI_ERROR (
SafeUintnToUint32 (LocalSize, &GetInfoParamsInternal->OutputVariableNameSize))) {
376 PolicyCommHeader->Result = EFI_BAD_BUFFER_SIZE;
380 ASSERT (
sizeof (GetInfoParamsInternal->OutputPolicyEntry) == sizeof (GetInfoParamsExternal->OutputPolicyEntry));
382 &GetInfoParamsExternal->OutputPolicyEntry,
383 &GetInfoParamsInternal->OutputPolicyEntry,
384 sizeof (GetInfoParamsExternal->OutputPolicyEntry)
387 GetInfoParamsExternal->OutputVariableNameSize = GetInfoParamsInternal->OutputVariableNameSize;
388 if (SubCommandStatus == EFI_BUFFER_TOO_SMALL) {
389 PolicyCommHeader->Result = EFI_BUFFER_TOO_SMALL;
394 ((
UINTN)GetInfoParamsExternal + VAR_CHECK_POLICY_COMM_GET_INFO_PARAMS_END),
395 (
UINTN)GetInfoParamsInternal->InputVariableNameSize,
396 (
UINTN *)&ExternalCopyOfOutputVariableName
398 if (EFI_ERROR (SubCommandStatus)) {
399 PolicyCommHeader->Result = EFI_BAD_BUFFER_SIZE;
403 if (GetInfoParamsInternal->OutputVariableNameSize > 0) {
405 ExternalCopyOfOutputVariableName,
406 AllowedOutputVariableNameSize,
407 InternalCopyOfOutputVariableName,
408 (
UINTN)GetInfoParamsInternal->OutputVariableNameSize
415 SetMem (ExternalCopyOfOutputVariableName, AllowedOutputVariableNameSize, CHAR_NULL);
418 PolicyCommHeader->Result = SubCommandStatus;
424 DEBUG ((DEBUG_INFO,
"%a - Invalid command requested! %d\n", __func__, PolicyCommHeader->Command));
425 PolicyCommHeader->Result = EFI_UNSUPPORTED;
431 "%a - Command %d returning %r.\n",
433 PolicyCommHeader->Command,
434 PolicyCommHeader->Result
449VarCheckPolicyLibCommonConstructor (
457 Status = InitVariablePolicyLib (VariableServiceGetVariable);
460 if (!EFI_ERROR (Status)) {
466 DiscardedHandle =
NULL;
467 Status = gMmst->MmiHandlerRegister (
468 VarCheckPolicyLibMmiHandler,
469 &gVarCheckPolicyLibMmiHandlerGuid,
475 DEBUG ((DEBUG_ERROR,
"%a - Cannot Initialize VariablePolicyLib! %r\n", __func__, Status));
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)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
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)
EFI_STATUS EFIAPI VarCheckLibRegisterSetVariableCheckHandler(IN VAR_CHECK_SET_VARIABLE_CHECK_HANDLER Handler)