From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=209.132.183.28; helo=mx1.redhat.com; envelope-from=lersek@redhat.com; receiver=edk2-devel@lists.01.org Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2FB9321E781EA for ; Tue, 3 Oct 2017 14:25:29 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 71F64C04B92E; Tue, 3 Oct 2017 21:28:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 71F64C04B92E Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=lersek@redhat.com Received: from lacos-laptop-7.usersys.redhat.com (ovpn-122-192.rdu2.redhat.com [10.10.122.192]) by smtp.corp.redhat.com (Postfix) with ESMTP id 100AB60F82; Tue, 3 Oct 2017 21:28:47 +0000 (UTC) From: Laszlo Ersek To: edk2-devel-01 Cc: Eric Dong , Jiewen Yao , Ladi Prosek , Star Zeng Date: Tue, 3 Oct 2017 23:28:33 +0200 Message-Id: <20171003212834.25740-6-lersek@redhat.com> In-Reply-To: <20171003212834.25740-1-lersek@redhat.com> References: <20171003212834.25740-1-lersek@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 03 Oct 2017 21:28:49 +0000 (UTC) Subject: [PATCH 5/6] MdeModulePkg/Variable/RuntimeDxe: delay MorLock creation until EndOfDxe X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Oct 2017 21:25:29 -0000 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 Cc: Jiewen Yao Cc: Ladi Prosek Cc: Star Zeng Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=727 Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1496170 Reported-by: Ladi Prosek Suggested-by: Jiewen Yao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Laszlo Ersek --- MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c | 62 ++++++++++++++++++-- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c index 1f495f847212..6d14b0042f4d 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/TcgMorLockSmm.c +++ b/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; @@ -394,10 +395,8 @@ MorLockInit ( VOID ) { - // - // Set variable to report capability to OS - // - return SetMorLockVariable (0); + mMorLockInitializationRequired = TRUE; + return EFI_SUCCESS; } /** @@ -410,7 +409,60 @@ 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. Do nothing. + // + return; + } + // - // Do nothing. + // Check if the MOR variable exists. // + MorSize = 0; + MorStatus = VariableServiceGetVariable ( + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, + &gEfiMemoryOverwriteControlDataGuid, + NULL, // Attributes + &MorSize, + NULL // Data + ); + // + // 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 + ); } -- 2.14.1.3.gb7cf6e02401b