From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.78]) by mx.groups.io with SMTP id smtpd.web10.2838.1608065585659062568 for ; Tue, 15 Dec 2020 12:53:05 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amdcloud.onmicrosoft.com header.s=selector2-amdcloud-onmicrosoft-com header.b=eyAZbV58; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.237.78, mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TLm/XLZ9wLDfO638/bc4bvmVnBTyacOQ4vzg0tB4C+12IAQV54DKpFzuG0G0eX6DFFl+ib4HLGX+3VgswwFEqDcueTZZ64xK0sDUnCu2uNj+5a7sNu3jECRUkAd7wrE2EF24iBOuj5A9EBOHJ8rM0Ycwam5T0lZWaiFV1czU009w04sQHxBrftaXdhe1bioFyVT6fBPG1t99iT6958o5yTopv7SGa7OIGC1g3vfM4eQnHjSav8HFnvgFuhXjN9bdTdch5XWVxTJWX6B9AGQr1x8FzOOCqc2IeKB1se2eGst2UkkkaRS9pMGRO9w90x5ZTujNC50axnnPKxrclwm4aA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IU0tN8kqIwF0BhCWAHrQOnqr1P+svXJXB18DtHcIfSE=; b=UfVX2U1kQQulVW2XcwMvOrhVdxILkbtfO48YbEm9KwG0ISItKtthreiTya9kT9gbm4VEgmBzCE2fNpQE+k7Kt9a8frlzjRYDwX9PZW+PRh53Z553i8pb4QAGKjIVhAsCc2hRQgOO4RgihLTWH+uzp8EQTyBeILU9y7LWid1nyB9h9zTD6qIoFK/s9isy+4QGUmE9/3/gSWO+980t4BnXTNDUMobEex01gwVo6Wsx1qRsNJ0nqKp5ztkHlIMpxtJJ0G4l/7UmMYQ5Zu7F+DQUildHcZXbsyD9S8ligM8YmHK6jg/7ZQqEfG1zChrHqOapMvZZANf2yOVl7cIyd7qemA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector2-amdcloud-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IU0tN8kqIwF0BhCWAHrQOnqr1P+svXJXB18DtHcIfSE=; b=eyAZbV580tkGZmgTaMQIcCUjuFsWT3xmcSFY1b9rIQQJeST1tmPgl/usQXrgxJRwE1ngcxOXH+0px8NN75Q2FA2skSps8/1Mb5tPafiozJfKgtLb8sY3MX+0KJu4Ix7y9B4Dfumcc3r44VsiAbEQa8IYcUVp7FeDdwEykkhhhvU= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=amd.com; Received: from DM5PR12MB1355.namprd12.prod.outlook.com (10.168.234.7) by DM6PR12MB4155.namprd12.prod.outlook.com (10.141.8.79) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.15; Tue, 15 Dec 2020 20:53:03 +0000 Received: from DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::d95e:b9d:1d6a:e845]) by DM5PR12MB1355.namprd12.prod.outlook.com ([fe80::d95e:b9d:1d6a:e845%12]) with mapi id 15.20.3654.025; Tue, 15 Dec 2020 20:53:03 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io CC: Brijesh Singh , James Bottomley , Jordan Justen , Laszlo Ersek , Ard Biesheuvel Subject: [PATCH 12/12] OvfmPkg/VmgExitLib: Validate #VC MMIO is to un-encrypted memory Date: Tue, 15 Dec 2020 14:51:11 -0600 Message-ID: <36dee4fe5bcc0d982b25a429fd37269bce72346e.1608065471.git.thomas.lendacky@amd.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: References: X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: CH2PR03CA0020.namprd03.prod.outlook.com (2603:10b6:610:59::30) To DM5PR12MB1355.namprd12.prod.outlook.com (2603:10b6:3:6e::7) Return-Path: thomas.lendacky@amd.com MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from tlendack-t1.amd.com (165.204.77.1) by CH2PR03CA0020.namprd03.prod.outlook.com (2603:10b6:610:59::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12 via Frontend Transport; Tue, 15 Dec 2020 20:53:02 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: 90562975-9653-4e6e-960d-08d8a13b6a4a X-MS-TrafficTypeDiagnostic: DM6PR12MB4155: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: tk58LTj6PDmeEE3ZeR3NPbqarD0GJ9rKB/7Hxn/ZGAWWLqcM9eZSs+TbIyIoWT1H2DNSnNib8OlcAXvpjNa+QKNbK0Sb61pO75PNzoIbm3SJqyEwv6zOj+9/JyfDjdLalfnNjFgi1k8vMq84WCGcPabOlMQxw4PFkjSisDfI2G0xWlsCYMrj35lD/YVFeQmKW+N94g9znPD0ntakkMWQdt0SywVAzl+v/w/LDTAs+ojGzEa1HlFwQjSZSvID9hr6Gw16IBYEGNUF7CXzIVrNPc1bX+asf7lR+qJgrxW5+3T9ki/8fqOvl+nx/rNsAqRKtflpk3qCQQgYvEFoD21u9xwbL1SOggdjK5obEEBqzSM4oUwgIyNzIU6IZl3ixuim7ShfGTeefXEekWITBxSALLmulVNgjvlal8k4/9fRmYvO1BrxJMg8sXm+NuNA3iBXnW56fwwJ8M0vPAqPVGzHgw== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM5PR12MB1355.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(376002)(366004)(136003)(346002)(66946007)(26005)(4326008)(19627235002)(16526019)(45954011)(6916009)(8676002)(36756003)(508600001)(52116002)(6666004)(83380400001)(5660300002)(8936002)(966005)(186003)(54906003)(956004)(2616005)(66476007)(2906002)(86362001)(34490700003)(6486002)(66556008)(15650500001)(7696005);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?gbEIhvl436RWpRqmJYybcwcwqwT6wZWttrc/ccvtRXUXGPkxgyLLjP5NDyUs?= =?us-ascii?Q?6NgVPJSh3+TYHdU/o5neP3skj5l3A70h+/4qJhmS49U5KwmbaJrolCgHf1Fx?= =?us-ascii?Q?HNUzokKSqacA1prEQ1KbL1fvxYzVK1Zv95+tmieyHaXe/P3nxTVTOQUmAKuI?= =?us-ascii?Q?ty81fz8lZFfUTYPw5PqYaisPuLLJcWmyqfEMMvBtMU+7adCTsKfJfMoBHTuQ?= =?us-ascii?Q?bMM+glc+rB5sVKmdnUhMTcWAL7E/JYg4b3rgmQNDgeKm13ckl71XdppgWIcJ?= =?us-ascii?Q?cLFL86ND8H6Eg2pgd/Yi2GRXoy/huVsaWtuCFna+G9mqm9EEbuIbdMe17WGy?= =?us-ascii?Q?rCK7J+VlBgQTxfkSlkPx4GHszAdhntN86zcvfiHPbERz7TPAekgvjCFFBpXO?= =?us-ascii?Q?1Q4rcWAjw4rnT17gnYX3TMIPA2IiwZMWraMStzMtksThUVhq0fj4PO9utPbu?= =?us-ascii?Q?6Y9Ov3XUL211VzBXFxeWm6Z460TCOuEL24CdOYczeIbPb73hM9WhhlutMimB?= =?us-ascii?Q?D2g/pGOmzoiHwe2+2GEMLXjZat8WCc2UYyQ2iBmO6m4Tgc62W0v87ImqC1l8?= =?us-ascii?Q?GPr72lp1ydmYtihkgU51hfKCytRHwkBbln8/IQ1KVGc4zluXgql5lHW+RKst?= =?us-ascii?Q?D9j7cEwR2dGW/9RqZDHRNSGri+mUcFsuLDaw2yIRKV8ZumIH+97Qiq4vWqVw?= =?us-ascii?Q?Nx9PPfuoKujkT3H8AbvBgK7L/yr1ZtM086Mi83nCQAWlJIjWfXIhjVMW+Bg6?= =?us-ascii?Q?Um2TjKwUZ4z2TaSBo5UcM68bXGmrcGSGM7udXpgjOA/fcwxW4I8RuwOtotfi?= =?us-ascii?Q?5WorD8x0V4CIadZ76hnDwV9x4tYKLNrq8HEgTbijh/sIjNwVsTWctrAXi5Gz?= =?us-ascii?Q?UrxBeBxciwShtm0JmgfzG73yqIhLU0uLR5u1/UKza0JXpACdWAqWW05zuUGF?= =?us-ascii?Q?Kg309WUqA5FAL/mriH+UFzhttW+mlltMVFy5TG3kP2n/Su5k0DQCf7sye/OY?= =?us-ascii?Q?33qg?= X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthSource: DM5PR12MB1355.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Dec 2020 20:53:02.9641 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: 90562975-9653-4e6e-960d-08d8a13b6a4a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: dg1JqJ2MrMAJMsjowGi5x/XeW4t/rvXSfoWjPkH8yWixO7CgeGvFtl/YSQpLNRFPvxFTRBaE9M831EEKTPd98w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4155 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable From: Tom Lendacky BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3108 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 Cc: Laszlo Ersek Cc: Ard Biesheuvel Cc: Brijesh Singh Signed-off-by: Tom Lendacky --- OvmfPkg/AmdSev/AmdSevX64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + .../DxeBaseMemEncryptSevLib.inf | 2 +- OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf | 1 + OvmfPkg/Library/VmgExitLib/VmgExitLib.inf | 2 + OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 81 +++++++++++++++++++ 6 files changed, 87 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index 3e5a3f648ad5..d0e9d28fc492 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.dsc +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc @@ -237,6 +237,7 @@ [LibraryClasses.common.SEC] CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiC= puExceptionHandlerLib.inf !endif VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf + MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptS= evLib.inf =20 [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index 226b576545a9..2a230888c636 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -265,6 +265,7 @@ [LibraryClasses.common.SEC] CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiC= puExceptionHandlerLib.inf !endif VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf + MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecBaseMemEncryptS= evLib.inf =20 [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.i= nf b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf index 04728a5dd256..10f794759207 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeBaseMemEncryptSevLib.inf @@ -14,7 +14,7 @@ [Defines] FILE_GUID =3D c1594631-3888-4be4-949f-9c630dbc842b MODULE_TYPE =3D BASE VERSION_STRING =3D 1.0 - LIBRARY_CLASS =3D MemEncryptSevLib|DXE_DRIVER DXE_RUNTI= ME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER + LIBRARY_CLASS =3D MemEncryptSevLib|DXE_CORE DXE_DRIVER = DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_DRIVER =20 # # The following information is for reference only and not required by the = build diff --git a/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf b/OvmfPkg/Library= /VmgExitLib/SecVmgExitLib.inf index df14de3c21bc..9c8de326f3d1 100644 --- a/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf +++ b/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf @@ -35,6 +35,7 @@ [LibraryClasses] BaseLib BaseMemoryLib DebugLib + MemEncryptSevLib PcdLib =20 [FixedPcd] diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf b/OvmfPkg/Library/Vm= gExitLib/VmgExitLib.inf index b3c3e56ecff8..c66c68726cdb 100644 --- a/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf +++ b/OvmfPkg/Library/VmgExitLib/VmgExitLib.inf @@ -35,4 +35,6 @@ [LibraryClasses] BaseLib BaseMemoryLib DebugLib + LocalApicLib + MemEncryptSevLib =20 diff --git a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c b/OvmfPkg/Librar= y/VmgExitLib/VmgExitVcHandler.c index ce577e4677eb..24259060fd65 100644 --- a/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c +++ b/OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -595,6 +596,61 @@ UnsupportedExit ( return Status; } =20 +/** + 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 allo= wed. + + @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 =3D MemoryAddress & ~(SIZE_4KB - 1); + if (Address =3D=3D GetLocalApicBaseAddress ()) { + return 0; + } + + State =3D MemEncryptSevGetAddressRangeState ( + 0, + MemoryAddress, + MemoryLength + ); + if (State =3D=3D MemEncryptSevAddressRangeUnencrypted) { + return 0; + } + + // + // Any state other than unencrypted is an error, issue a #GP. + // + GpEvent.Uint64 =3D 0; + GpEvent.Elements.Vector =3D GP_EXCEPTION; + GpEvent.Elements.Type =3D GHCB_EVENT_INJECTION_TYPE_EXCEPTION; + GpEvent.Elements.Valid =3D 1; + + return GpEvent.Uint64; +} + /** Handle an MMIO event. =20 @@ -653,6 +709,11 @@ MmioExit ( return UnsupportedExit (Ghcb, Regs, InstructionData); } =20 + Status =3D ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Byte= s); + if (Status !=3D 0) { + return Status; + } + ExitInfo1 =3D InstructionData->Ext.RmData; ExitInfo2 =3D Bytes; CopyMem (Ghcb->SharedBuffer, &InstructionData->Ext.RegData, Bytes); @@ -683,6 +744,11 @@ MmioExit ( InstructionData->ImmediateSize =3D Bytes; InstructionData->End +=3D Bytes; =20 + Status =3D ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Byte= s); + if (Status !=3D 0) { + return Status; + } + ExitInfo1 =3D InstructionData->Ext.RmData; ExitInfo2 =3D Bytes; CopyMem (Ghcb->SharedBuffer, InstructionData->Immediate, Bytes); @@ -717,6 +783,11 @@ MmioExit ( return UnsupportedExit (Ghcb, Regs, InstructionData); } =20 + Status =3D ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Byte= s); + if (Status !=3D 0) { + return Status; + } + ExitInfo1 =3D InstructionData->Ext.RmData; ExitInfo2 =3D Bytes; =20 @@ -748,6 +819,11 @@ MmioExit ( case 0xB7: Bytes =3D (Bytes !=3D 0) ? Bytes : 2; =20 + Status =3D ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Byte= s); + if (Status !=3D 0) { + return Status; + } + ExitInfo1 =3D InstructionData->Ext.RmData; ExitInfo2 =3D Bytes; =20 @@ -774,6 +850,11 @@ MmioExit ( case 0xBF: Bytes =3D (Bytes !=3D 0) ? Bytes : 2; =20 + Status =3D ValidateMmioMemory (Ghcb, InstructionData->Ext.RmData, Byte= s); + if (Status !=3D 0) { + return Status; + } + ExitInfo1 =3D InstructionData->Ext.RmData; ExitInfo2 =3D Bytes; =20 --=20 2.28.0