mirror of https://github.com/acidanthera/audk.git
OvfmPkg/VmgExitLib: Validate #VC MMIO is to un-encrypted memory
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3108 When SEV-ES is active, and MMIO operation will trigger a #VC and the VmgExitLib exception handler will process this MMIO operation. A malicious hypervisor could try to extract information from encrypted memory by setting a reserved bit in the guests nested page tables for a non-MMIO area. This can result in the encrypted data being copied into the GHCB shared buffer area and accessed by the hypervisor. Prevent this by ensuring that the MMIO source/destination is un-encrypted memory. For the APIC register space, access is allowed in general. Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Ard Biesheuvel <ard.biesheuvel@arm.com> Cc: Brijesh Singh <brijesh.singh@amd.com> Acked-by: Laszlo Ersek <lersek@redhat.com> Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com> Message-Id: <0cf28470ad5e694af45f7f0b35296628f819567d.1610045305.git.thomas.lendacky@amd.com>
This commit is contained in:
parent
362654246a
commit
85b8eac59b
|
@ -237,6 +237,7 @@
|
||||||
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
|
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
|
||||||
!endif
|
!endif
|
||||||
VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
|
VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
|
||||||
|
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.PEI_CORE]
|
[LibraryClasses.common.PEI_CORE]
|
||||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
FILE_GUID = c1594631-3888-4be4-949f-9c630dbc842b
|
FILE_GUID = c1594631-3888-4be4-949f-9c630dbc842b
|
||||||
MODULE_TYPE = BASE
|
MODULE_TYPE = BASE
|
||||||
VERSION_STRING = 1.0
|
VERSION_STRING = 1.0
|
||||||
LIBRARY_CLASS = MemEncryptSevLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER
|
LIBRARY_CLASS = MemEncryptSevLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER
|
||||||
|
|
||||||
#
|
#
|
||||||
# The following information is for reference only and not required by the build
|
# The following information is for reference only and not required by the build
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
BaseLib
|
BaseLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
DebugLib
|
DebugLib
|
||||||
|
LocalApicLib
|
||||||
|
MemEncryptSevLib
|
||||||
PcdLib
|
PcdLib
|
||||||
|
|
||||||
[FixedPcd]
|
[FixedPcd]
|
||||||
|
|
|
@ -35,4 +35,6 @@
|
||||||
BaseLib
|
BaseLib
|
||||||
BaseMemoryLib
|
BaseMemoryLib
|
||||||
DebugLib
|
DebugLib
|
||||||
|
LocalApicLib
|
||||||
|
MemEncryptSevLib
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <Base.h>
|
#include <Base.h>
|
||||||
#include <Uefi.h>
|
#include <Uefi.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
|
#include <Library/LocalApicLib.h>
|
||||||
#include <Library/MemEncryptSevLib.h>
|
#include <Library/MemEncryptSevLib.h>
|
||||||
#include <Library/VmgExitLib.h>
|
#include <Library/VmgExitLib.h>
|
||||||
#include <Register/Amd/Msr.h>
|
#include <Register/Amd/Msr.h>
|
||||||
|
@ -595,6 +596,61 @@ UnsupportedExit (
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Validate that the MMIO memory access is not to encrypted memory.
|
||||||
|
|
||||||
|
Examine the pagetable entry for the memory specified. MMIO should not be
|
||||||
|
performed against encrypted memory. MMIO to the APIC page is always allowed.
|
||||||
|
|
||||||
|
@param[in] Ghcb Pointer to the Guest-Hypervisor Communication Block
|
||||||
|
@param[in] MemoryAddress Memory address to validate
|
||||||
|
@param[in] MemoryLength Memory length to validate
|
||||||
|
|
||||||
|
@retval 0 Memory is not encrypted
|
||||||
|
@return New exception value to propogate
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
UINT64
|
||||||
|
ValidateMmioMemory (
|
||||||
|
IN GHCB *Ghcb,
|
||||||
|
IN UINTN MemoryAddress,
|
||||||
|
IN UINTN MemoryLength
|
||||||
|
)
|
||||||
|
{
|
||||||
|
MEM_ENCRYPT_SEV_ADDRESS_RANGE_STATE State;
|
||||||
|
GHCB_EVENT_INJECTION GpEvent;
|
||||||
|
UINTN Address;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Allow APIC accesses (which will have the encryption bit set during
|
||||||
|
// SEC and PEI phases).
|
||||||
|
//
|
||||||
|
Address = MemoryAddress & ~(SIZE_4KB - 1);
|
||||||
|
if (Address == GetLocalApicBaseAddress ()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
State = MemEncryptSevGetAddressRangeState (
|
||||||
|
0,
|
||||||
|
MemoryAddress,
|
||||||
|
MemoryLength
|
||||||
|
);
|
||||||
|
if (State == MemEncryptSevAddressRangeUnencrypted) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Any state other than unencrypted is an error, issue a #GP.
|
||||||
|
//
|
||||||
|
GpEvent.Uint64 = 0;
|
||||||
|
GpEvent.Elements.Vector = GP_EXCEPTION;
|
||||||
|
GpEvent.Elements.Type = GHCB_EVENT_INJECTION_TYPE_EXCEPTION;
|
||||||
|
GpEvent.Elements.Valid = 1;
|
||||||
|
|
||||||
|
return GpEvent.Uint64;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Handle an MMIO event.
|
Handle an MMIO event.
|
||||||
|
|
||||||
|
@ -653,6 +709,11 @@ MmioExit (
|
||||||
return UnsupportedExit (Ghcb, Regs, InstructionData);
|
return UnsupportedExit (Ghcb, Regs, InstructionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
||||||
|
if (Status != 0) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
ExitInfo1 = InstructionData->Ext.RmData;
|
ExitInfo1 = InstructionData->Ext.RmData;
|
||||||
ExitInfo2 = Bytes;
|
ExitInfo2 = Bytes;
|
||||||
CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes);
|
CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes);
|
||||||
|
@ -683,6 +744,11 @@ MmioExit (
|
||||||
InstructionData->ImmediateSize = Bytes;
|
InstructionData->ImmediateSize = Bytes;
|
||||||
InstructionData->End += Bytes;
|
InstructionData->End += Bytes;
|
||||||
|
|
||||||
|
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
||||||
|
if (Status != 0) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
ExitInfo1 = InstructionData->Ext.RmData;
|
ExitInfo1 = InstructionData->Ext.RmData;
|
||||||
ExitInfo2 = Bytes;
|
ExitInfo2 = Bytes;
|
||||||
CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes);
|
CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes);
|
||||||
|
@ -717,6 +783,11 @@ MmioExit (
|
||||||
return UnsupportedExit (Ghcb, Regs, InstructionData);
|
return UnsupportedExit (Ghcb, Regs, InstructionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
||||||
|
if (Status != 0) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
ExitInfo1 = InstructionData->Ext.RmData;
|
ExitInfo1 = InstructionData->Ext.RmData;
|
||||||
ExitInfo2 = Bytes;
|
ExitInfo2 = Bytes;
|
||||||
|
|
||||||
|
@ -748,6 +819,11 @@ MmioExit (
|
||||||
case 0xB7:
|
case 0xB7:
|
||||||
Bytes = (Bytes != 0) ? Bytes : 2;
|
Bytes = (Bytes != 0) ? Bytes : 2;
|
||||||
|
|
||||||
|
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
||||||
|
if (Status != 0) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
ExitInfo1 = InstructionData->Ext.RmData;
|
ExitInfo1 = InstructionData->Ext.RmData;
|
||||||
ExitInfo2 = Bytes;
|
ExitInfo2 = Bytes;
|
||||||
|
|
||||||
|
@ -774,6 +850,11 @@ MmioExit (
|
||||||
case 0xBF:
|
case 0xBF:
|
||||||
Bytes = (Bytes != 0) ? Bytes : 2;
|
Bytes = (Bytes != 0) ? Bytes : 2;
|
||||||
|
|
||||||
|
Status = ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Bytes);
|
||||||
|
if (Status != 0) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
ExitInfo1 = InstructionData->Ext.RmData;
|
ExitInfo1 = InstructionData->Ext.RmData;
|
||||||
ExitInfo2 = Bytes;
|
ExitInfo2 = Bytes;
|
||||||
|
|
||||||
|
|
|
@ -266,6 +266,7 @@
|
||||||
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
|
CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiCpuExceptionHandlerLib.inf
|
||||||
!endif
|
!endif
|
||||||
VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
|
VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf
|
||||||
|
MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.PEI_CORE]
|
[LibraryClasses.common.PEI_CORE]
|
||||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||||
|
|
Loading…
Reference in New Issue