Permalink
Browse files

MdeModulePkg/Variable/RuntimeDxe: delay MorLock creation until EndOfDxe

The "MemoryOverwriteRequestControl" (a.k.a. MOR) variable comes from the
"TCG Platform Reset Attack Mitigation Specification":

https://www.trustedcomputinggroup.org/wp-content/uploads/Platform-Reset-Attack-Mitigation-Specification.pdf

The "MemoryOverwriteRequestControlLock" variable (a.k.a. MORL) is a
Microsoft extension, called "Secure MOR implementation":

https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/device-guard-requirements

Currently the VariableSmm driver creates MORL without regard to MOR. This
can lead to a situation where a platform does not support MOR from the
prerequisite spec (because it does not include the
"SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf" driver), but appears
to support MORL from the dependent Microsoft spec.

"winload.efi" notices this inconsistency, and disables the Device Guard
Virtualization Based Security in Windows Server 2016 and Windows 10 64-bit
Enterprise.

If the platform includes
"SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf", then MOR will exist
by the time EndOfDxe is reached, and VariableSmm can safely create MORL.
Otherwise, do not create MORL (delete it if it exists), and also prevent
other modules from creating it.

Cc: Eric Dong <eric.dong@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ladi Prosek <lprosek@redhat.com>
Cc: Star Zeng <star.zeng@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=727
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1496170
Reported-by: Ladi Prosek <lprosek@redhat.com>
Suggested-by: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Tested-by: Ladi Prosek <lprosek@redhat.com>
  • Loading branch information...
lersek committed Sep 30, 2017
1 parent e353116 commit 7516532f9c2ddc263040c5989b3adc7fb47fb401
Showing with 58 additions and 5 deletions.
  1. +58 −5 MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c
@@ -45,6 +45,7 @@ typedef enum {
MorLockStateLocked = 1,
} MOR_LOCK_STATE;
BOOLEAN mMorLockInitializationRequired = FALSE;
UINT8 mMorLockKey[MOR_LOCK_V2_KEY_SIZE];
BOOLEAN mMorLockKeyEmpty = TRUE;
BOOLEAN mMorLockPassThru = FALSE;
@@ -392,10 +393,8 @@ MorLockInit (
VOID
)
{
//
// Set variable to report capability to OS
//
return SetMorLockVariable (0);
mMorLockInitializationRequired = TRUE;
return EFI_SUCCESS;
}
/**
@@ -408,7 +407,61 @@ MorLockInitAtEndOfDxe (
VOID
)
{
UINTN MorSize;
EFI_STATUS MorStatus;
if (!mMorLockInitializationRequired) {
//
// The EFI_SMM_FAULT_TOLERANT_WRITE_PROTOCOL has never been installed, thus
// the variable write service is unavailable. This should never happen.
//
ASSERT (FALSE);
return;
}
//
// Check if the MOR variable exists.
//
MorSize = 0;
MorStatus = VariableServiceGetVariable (
MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
&gEfiMemoryOverwriteControlDataGuid,
NULL, // Attributes
&MorSize,
NULL // Data
);
//
// Do nothing.
// We provided a zero-sized buffer, so the above call can never succeed.
//
ASSERT (EFI_ERROR (MorStatus));
if (MorStatus == EFI_BUFFER_TOO_SMALL) {
//
// The MOR variable exists; set the MOR Control Lock variable to report the
// capability to the OS.
//
SetMorLockVariable (0);
return;
}
//
// The platform does not support the MOR variable. Delete the MOR Control
// Lock variable (should it exists for some reason) and prevent other modules
// from creating it.
//
mMorLockPassThru = TRUE;
VariableServiceSetVariable (
MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,
&gEfiMemoryOverwriteRequestControlLockGuid,
0, // Attributes
0, // DataSize
NULL // Data
);
mMorLockPassThru = FALSE;
VariableLockRequestToLock (
NULL, // This
MEMORY_OVERWRITE_REQUEST_CONTROL_LOCK_NAME,
&gEfiMemoryOverwriteRequestControlLockGuid
);
}

0 comments on commit 7516532

Please sign in to comment.