From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id A7A0D7803CE for ; Thu, 11 Jul 2024 06:42:32 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=ajWrXZwKKrbxzMWeKWVDULJJWYad77ucUa8DcUwPdwU=; c=relaxed/simple; d=groups.io; h=Subject:To:From:User-Agent:MIME-Version:Date:References:In-Reply-To:Message-ID:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type; s=20240206; t=1720680152; v=1; b=aY9i9z7bUZ27k0ibMITkTZAF74q2YWyPfKgnXEj8UN2iT1l9g2t4uFU8BtfM8Ah6jIdDHSrv vrC0pEzngNh1pDcz0rb79mZYUqkri/vrSETzxcGi689ks9KIa0QDJ8kBEiZzxfAWpDp+w30RsWK m6916MnUA3YYy5iRSBZDnLpusNvc2qQ6gCc3a0xaFGFiZ00FlMIzCx5I4q6+RR+5mT8dkXKSEOD MANAjY2E07d4sCLWLRLeWhVQqelBKkWhB6TGzhdEBqqlI0/T+7XPxQ3ICagvkzXwxv7WN+2Ojel 0Vdoxkhf87AgEYLnCJj4sdmKalrnt4yDBmdJCLMPO6B2A== X-Received: by 127.0.0.2 with SMTP id sLUCYY7687511x5ecwv8d1Uc; Wed, 10 Jul 2024 23:42:31 -0700 Subject: Re: [edk2-devel] The OVMF packages can not work properly when it was compiled with "-D SECURE_BOOT_ENABLE=TRUE" To: wojiaohanliyang@163.com, devel@edk2.groups.io From: wojiaohanliyang@163.com X-Originating-Location: CN (118.242.3.34) X-Originating-Platform: Windows Chrome 126 User-Agent: GROUPS.IO Web Poster MIME-Version: 1.0 Date: Wed, 10 Jul 2024 23:42:30 -0700 References: In-Reply-To: Message-ID: <18500.1720680150587411874@groups.io> Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,wojiaohanliyang@163.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: h77GzkdzdcnhiOnj2AHbxzbax7686176AA= Content-Type: multipart/alternative; boundary="DLGviVmXfQJJh2iHxnf0" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=aY9i9z7b; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=163.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io --DLGviVmXfQJJh2iHxnf0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The root cause of these issues are that the following patchset rename the f= unction from TdxValidateCfv() to PlatformInitEmuVariableNvStore(). 39596c41c8 OvmfPkg: Add build-flag SECURE_BOOT_FEATURE_ENABLED 3abaa281d3 OvmfPkg/TdxDxe: Set PcdEmuVariableNvStoreReserved 70165fa6e2 OvmfPkg/NvVarsFileLib: Shortcut ConnectNvVarsToFileSystem in sec= ure-boot ee91d9ef24 OvmfPkg: Reserve and init EmuVariableNvStore in Pei-less Startup *58eb8517ad OvmfPkg/PlatformPei: Update ReserveEmuVariableNvStore* *4f173db8b4 OvmfPkg/PlatformInitLib: Add functions for EmuVariableNvStore* *0e72e8762a OvmfPkg/PeilessStartupLib: Delete TdxValidateCfv* fb008dbe01 EmbeddedPkg: Add AllocateRuntimePages in PrePiMemoryAllocationLi= b 7cc7c52670 OvmfPkg: Set default Pci PCDs in Tdx guest 1b1c58ab32 OvmfPkg: Update CcProbeLib to DxeCcProbeLib c4bc1a9498 OvmfPkg: Add SecPeiCcProbeLib Before the patchset is merged, the TdxValidateCfv() is invoked only in Tdx = guest. After the patchset is merged, the PlatformInitEmuVariableNvStore() b= ecomes a common code and is invoked in any guest. The code path is as below= . PlatformPei/InitializePlatform() -> ReserveEmuVarabileNvStore() *-> PlatformInitEmuVariableNvStore() if 'SECURE_BOOT_ENABLE=3DTRUE'* *-> PlatformValidateNvVarStore()* The function PlatformValidateNvVarStore() will access the OvmfFlashNvStorag= e which is mapped in the address range specified by 'PcdOvmfFlashNvStorageV= ariableBase' (typically 0xFFC00000) and 'PcdFlashNvStorageVariableSize' (ty= pically 0x40000). But the function PlatformValidateNvVarStore() doesn't con= sider any combination of OVMF files and Non-CoCo/CoCo guest. *1.* *When we boot a Qemu VM with only OVMF_CODE.fd but not OVMF_VARS.fd,* = the address range specified by 'PcdOvmfFlashNvStorageVariableBase' (typical= ly 0xFFC00000) and '2 * PcdFlashNvStorageFtwSpareSize' (typically 0x84000) = is mmio address range but without corresponding device. a. If the VM is a non-encrypted VM, the 0x0 is returned when PlatformValida= teNvVarStore() read from the mmio address range,=C2=A0 this will cause vali= dation of OvmfFlashNvStorage to fail and trigger ASSERT (FALSE). b. If the VM is a SEV VM, the PlatformValidateNvVarStore() calls IsZeroBuff= er() which execute instruction scasX to check that first 16 bytes of the Ov= mfFlashNvStorage are all zeros. On Linux host side, KVM will inject #PF whe= n it emulate scasX on MMIO address range, when VmEnter the guest, the guest= will trigger shutdown event because the exception handler can't deal with = #PF at this time. c. If the VM is a SEV-ES VM, the PlatformValidateNvVarStore() calls IsZeroB= uffer() which execute instruction scasX to check that first 16 bytes of the= OvmfFlashNvStorage are all zeros. The instruction scasX will trigger #VC h= andler to handle MMIO NPF event, the #VC handler can't decode scasX and tri= gger ASSERT (FALSE). *2. When we boot a Qemu VM with OVMF.fd ( the OVMF_VARS.fd part is included= in OVMF.fd),* the address range specified by 'PcdOvmfFlashNvStorageVariabl= eBase' (typically 0xFFC00000) and '2 * PcdFlashNvStorageFtwSpareSize' (typi= cally 0x84000) is mmio address range and the KVM will mapping the mmio addr= ess range to system physical memory with read-only attribute in the NPT whe= n guest read from this address range. a. If the VM is a SEV/SEV-ES VM, the PlaformValidateNvVarStore() can return= as expected, because at this time, the guest can direct read system physic= al memory for data in the mmio address range. But in this situation, Platfo= rmValidateNvVarStore() only initialize the first part (this part is specifi= ed by 'PcdFlashNvStorageVariableSize' in length) of EmuVariableNvStore buff= er, *the Fault Tolerant Write part of EmuVariableNvStore buffer isn't initi= alized at this time*. If the first part of EmuVariableNvStore is initilaize= d at here, then VariableRuntimeDxe will not initialize EmuVariableNvStore, = and FaultTolerantWriteDxe will get garble data from Fault Tolerant Write pa= rt of EmuVariableNvStore, the FaultTolerantWriteDxe read data from the addr= ess specified by the garble data will cause invalid access and crash. *3. When boot a Qemu VM with OVMF_CODE.fd and OVMF_VARS.fd,* the address ra= nge specified by 'PcdOvmfFlashNvStorageVariableBase' (typically 0xFFC00000)= and '2 * PcdFlashNvStorageFtwSpareSize' (typically 0x84000) is mmio addres= s range and the KVM will mapping the mmio address range to system physical = memory with read-only attribute in the NPT when guest read from this addres= s range. a. If the VM is a SEV/SEV-ES VM, the PlatformValidateNvVarStore() invokes I= sZeroBuffer() and find the first 16 bytes of the OvmfFlashNvStorage are not= all zeros, and then trigger ASSERT (FALSE). In this situation, the OvmfFla= shNvStorage is OVMF_VARS.fd=EF=BC=8Cthe OVMF_VARS.fd is plaintext on the ho= st side, while at this time, the guest mapping these address range with C-b= it (i.e. mapping as encrypted). The guest get garble data when it read the = first 16 bytes of the OvmfFlashNvStorage,=C2=A0 the validation will fail. -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#119888): https://edk2.groups.io/g/devel/message/119888 Mute This Topic: https://groups.io/mt/107157379/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --DLGviVmXfQJJh2iHxnf0 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable The root cause of these issues are that the following patchset rename the f= unction from TdxValidateCfv() to PlatformInitEmuVariableNvStore().
    39596c41c8 OvmfPkg: Add build-flag SECURE_BOOT_FEATURE= _ENABLED
    3abaa281d3 OvmfPkg/TdxDxe: Set PcdEmuV= ariableNvStoreReserved
    70165fa6e2 OvmfPkg/NvVar= sFileLib: Shortcut ConnectNvVarsToFileSystem in secure-boot
&= nbsp;   ee91d9ef24 OvmfPkg: Reserve and init EmuVariableNvStore in Pei= -less Startup
    58eb8517ad OvmfPkg/Platfo= rmPei: Update ReserveEmuVariableNvStore
&nbs= p;   4f173db8b4 OvmfPkg/PlatformInitLib: Add functions for EmuVariable= NvStore
    0e72e8762a OvmfPkg/Pei= lessStartupLib: Delete TdxValidateCfv
    = fb008dbe01 EmbeddedPkg: Add AllocateRuntimePages in PrePiMemoryAllocationLi= b
    7cc7c52670 OvmfPkg: Set default Pci PCDs in T= dx guest
    1b1c58ab32 OvmfPkg: Update CcProbeLib = to DxeCcProbeLib
    c4bc1a9498 OvmfPkg: Add SecPei= CcProbeLib

Before the patchset is merged, the TdxValidateCf= v() is invoked only in Tdx guest. After the patchset is merged, the Platfor= mInitEmuVariableNvStore() becomes a common code and is invoked in any guest= . The code path is as below.
     PlatformPei/Initializ= ePlatform()
         -> ReserveEmuVarabile= NvStore()
              &nb= sp;   -> PlatformInitEmuVariableNvStore() if 'SECURE_BOOT_ENABLE=3D= TRUE'
             = ;              -> PlatformValidateNvV= arStore()

The function PlatformValidateNvVarStore() wil= l access the OvmfFlashNvStorage which is mapped in the address range specif= ied by 'PcdOvmfFlashNvStorageVariableBase' (typically 0xFFC00000) and 'PcdF= lashNvStorageVariableSize' (typically 0x40000). But the function PlatformVa= lidateNvVarStore() doesn't consider any combination of OVMF files and Non-C= oCo/CoCo guest.

1. When we boot a Qemu = VM with only OVMF_CODE.fd but not OVMF_VARS.fd, the address range = specified by 'PcdOvmfFlashNvStorageVariableBase' (typically 0xFFC00000) and= '2 * PcdFlashNvStorageFtwSpareSize' (typically 0x84000) is mmio address ra= nge but without corresponding device.
     a. If the VM= is a non-encrypted VM, the 0x0 is returned when PlatformValidateNvVarStore= () read from the mmio address range,  this will cause validation of Ov= mfFlashNvStorage to fail and trigger ASSERT (FALSE).
    &nb= sp;b. If the VM is a SEV VM, the PlatformValidateNvVarStore() calls IsZeroB= uffer() which execute instruction scasX to check that first 16 bytes of the= OvmfFlashNvStorage are all zeros. On Linux host side, KVM will inject #PF = when it emulate scasX on MMIO address range, when VmEnter the guest, the gu= est will trigger shutdown event because the exception handler can't deal wi= th #PF at this time.
     c. If the VM is a SEV-ES VM, = the PlatformValidateNvVarStore() calls IsZeroBuffer() which execute instruc= tion scasX to check that first 16 bytes of the OvmfFlashNvStorage are all z= eros. The instruction scasX will trigger #VC handler to handle MMIO NPF eve= nt, the #VC handler can't decode scasX and trigger ASSERT (FALSE).
2. When we boot a Qemu VM with OVMF.fd ( the OVMF_VARS.fd part i= s included in OVMF.fd), the address range specified by 'PcdOvmfFla= shNvStorageVariableBase' (typically 0xFFC00000) and '2 * PcdFlashNvStorageF= twSpareSize' (typically 0x84000) is mmio address range and the KVM will map= ping the mmio address range to system physical memory with read-only attrib= ute in the NPT when guest read from this address range.
    = a. If the VM is a SEV/SEV-ES VM, the PlaformValidateNvVarStore() can return= as expected, because at this time, the guest can direct read system physic= al memory for data in the mmio address range. But in this situation, Platfo= rmValidateNvVarStore() only initialize the first part (this part is specifi= ed by 'PcdFlashNvStorageVariableSize' in length) of EmuVariableNvStore buff= er, the Fault Tolerant Write part of EmuVariableNvStore buffer isn'= t initialized at this time. If the first part of EmuVariableNvStor= e is initilaized at here, then VariableRuntimeDxe will not initialize EmuVa= riableNvStore, and FaultTolerantWriteDxe will get garble data from Fault To= lerant Write part of EmuVariableNvStore, the FaultTolerantWriteDxe read dat= a from the address specified by the garble data will cause invalid access a= nd crash.

3. When boot a Qemu VM with OVMF_CODE.fd and O= VMF_VARS.fd,  the address range specified by 'PcdOvmfFlashNvS= torageVariableBase' (typically 0xFFC00000) and '2 * PcdFlashNvStorageFtwSpa= reSize' (typically 0x84000) is mmio address range and the KVM will mapping = the mmio address range to system physical memory with read-only attribute i= n the NPT when guest read from this address range.
    a. If= the VM is a SEV/SEV-ES VM, the PlatformValidateNvVarStore() invokes IsZero= Buffer() and find the first 16 bytes of the OvmfFlashNvStorage are not all = zeros, and then trigger ASSERT (FALSE). In this situation, the OvmfFlashNvS= torage is OVMF_VARS.fd=EF=BC=8Cthe OVMF_VARS.fd is plaintext on the host si= de, while at this time, the guest mapping these address range with C-bit (i= .e. mapping as encrypted). The guest get garble data when it read the first= 16 bytes of the OvmfFlashNvStorage,  the validation will fail.
_._,_._,_

Groups.io Links:

=20 You receive all messages sent to this group. =20 =20

View/Reply Online (#119888) | =20 | Mute= This Topic | New Topic
Your Subscriptio= n | Contact Group Owner | Unsubscribe [rebecca@openfw.io]

_._,_._,_
--DLGviVmXfQJJh2iHxnf0--