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.74]) by mx.groups.io with SMTP id smtpd.web10.1177.1610045513516164514 for ; Thu, 07 Jan 2021 10:51:53 -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=36Z3ukbi; 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.74, mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lOyI8WmzgarkhsYStq8ewpytHp8IxFHnpBW072hsBOKga/loNmDkFQllPehm6TqWx76ALne1JjAVi+h8W5peUz5VtViIFUJVqWh0s2CtBsvMyB/1aEBCIqMHQOyXHxpHmGL9UfM49P61/fqJqiNUoUiGQhl+5KVNRF47gsk/yr1KdqbABUR6Lb7pctMsyTbQpHWV2/peKzhKGoTrQDxO3BbGhZaXB7JeRySonHV3ZyQ9ngq8N8YVmf+NxaOphqwNmWUj7aLzwPL7ovmuRSvrtO6BIh58j7oi4PQSSi1hMFZfIox6MH7JjW1J3dzeQXYFpN9aQnVaRl5KNu4QP29Uqw== 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=g0jJGCLWbaS71xsnMvQjLxVO5/5Hug1e4WlzEU8SkCo=; b=XIRPHiJ9dH/H/IGDJOKmBAuLXxN26Eq3nESFgBOL3LKeziWYCcuaSe7lOC76ln/oQKulUM0F7/Iw1aO2ffQqjf+b8A43H+DOqNmJnpTpU7bXZP1A6x0SPsPgdjJu3Szw0bkkmEgf5Ux+IS2m2Je5UJTq96C4RHUOHxkGB1/6dIQA4zTrwIFYHvlfTqTIyiK0tqTO/s5zeYnEgiBlXyckZykvAY6d+fsBrpG5EE1+z4qmhdkXw4RCUvnDmDV7A2GXMnFZrqpN2po1wGkjN/jf7rF3ce0ms5t6oo4avPtuTaqbI1kj9AQzzQ2SnM21HSAtIHukEKSn3wtBibFl4fN6Jg== 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=g0jJGCLWbaS71xsnMvQjLxVO5/5Hug1e4WlzEU8SkCo=; b=36Z3ukbi+p/yPgB6koJLcAmO6u/UdBN9lOq+NfaiMU3p7dSNgs57QjLJFAAfI9BfUy1a2SstLIzepHRHSGIoyDaxK14q/jUA6rI4JNCOVP8xyzDAOCL3MtE449asN/B9xHzoPRTpUnxTGAis2VGfqBtBwDnzBY3AlGFuIiG8yRQ= 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 (2603:10b6:3:6e::7) by DM6PR12MB4987.namprd12.prod.outlook.com (2603:10b6:5:163::31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3742.6; Thu, 7 Jan 2021 18:51:51 +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.3721.024; Thu, 7 Jan 2021 18:51:51 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io CC: Brijesh Singh , James Bottomley , Jordan Justen , Laszlo Ersek , Ard Biesheuvel Subject: [PATCH v3 15/15] OvfmPkg/VmgExitLib: Validate #VC MMIO is to un-encrypted memory Date: Thu, 7 Jan 2021 12:48:25 -0600 Message-ID: <0cf28470ad5e694af45f7f0b35296628f819567d.1610045305.git.thomas.lendacky@amd.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: References: X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SA0PR11CA0037.namprd11.prod.outlook.com (2603:10b6:806:d0::12) 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 SA0PR11CA0037.namprd11.prod.outlook.com (2603:10b6:806:d0::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3742.6 via Frontend Transport; Thu, 7 Jan 2021 18:51:51 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: f06ac571-6422-4cb6-4c91-08d8b33d4bbd X-MS-TrafficTypeDiagnostic: DM6PR12MB4987: 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: CM9RriTMe8wT1lH7erO715QqR1mpDuth0TACCsRNpeIR8oLdRIm46ZgQIuQ05p48JrTpGQ0oiNwbd4tikDGwAZF1mAzmoNHV6cLQ+/CN+lDkLKEPvIG+GTMD3IqsCq03vtOPIwABMcfLjPhzlhZMyH9cIevOAGZKVaCChYtBXyMSzcVbVMDmPunABFFeoXa2rajh+pztXyUTZ1TxIUNveq36+GLiPaNMpDpxpO2YuATL2SMi7LmVytiHcYog39Kc4nKQVs2T9HtyRYkxOKLzIkp3kqRZXjzoiVWztQs/Y7XROIil2xLnnAh3tUY7LGKyPyVJTs9b9LhsfnthcIt1kUaGjAAuZVrU1eKkUQZ3ybDopKtkOBs9n2KqLDbSFvFg2gz9DPaL87F4iGenbuuFwbWpQkOww62fDAO4iqYXut2Y0zR6U0lnW4IvPBneaVhvIx+yzCjBDr7Z6IlyPZvFCA== 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)(136003)(396003)(366004)(39860400002)(346002)(6916009)(36756003)(45954011)(8676002)(7696005)(52116002)(4326008)(5660300002)(966005)(83380400001)(6666004)(478600001)(316002)(66946007)(54906003)(66476007)(66556008)(2906002)(86362001)(8936002)(19627235002)(956004)(15650500001)(2616005)(186003)(26005)(6486002)(16526019);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?suUP/AbYZeBVZRXrcC5e4fF4iAhfPOiCThvYmahoiIoUjZUjDKeog0skQvTp?= =?us-ascii?Q?RTh1jgfdFxAzUDBUuZknCIS/Kr0PW6xK12oOf8cudR4JXl52y3uO6SbXAAd3?= =?us-ascii?Q?6mUxM7kXCjrkkjUHIgME9rIgVOBQOrkXrI9ZRMhAUeorJwM/SGyvps5SRZR1?= =?us-ascii?Q?2gmaOgXCMw1i2PF5ipYL0hMrSGGg6nErYQ9/Zdu7wG4UDN1mRNFPRKpz3WX7?= =?us-ascii?Q?/6HTETZBb/6i3qbX+i0YfAFUmRf7dlC8pnaTDgORbapI6JCjIWA2K1VXixTQ?= =?us-ascii?Q?WkwZX/P/tPS0go6Qa3FaZF1l/POvs55NAMf6Dtx1lXRK8yFr9X/LulmMwI5+?= =?us-ascii?Q?3T/cpI3w+usH2tCdaQ/5AJ9y1oLd97gMSSbSu+kK3LL1GFnL0cJRsHAtEMA8?= =?us-ascii?Q?xdc8TjCDe9ACDl7o+XNfjyxuJjPFf+AsiUz1S26aYjaVZe8R3GTX1FftU3Y+?= =?us-ascii?Q?JicPTdbiPpN8g7LP9ts3drvO5bKgxC4cPASUm5JX3EdCg0p4ulZJ7fdEbszR?= =?us-ascii?Q?6+xN6ihcOIUVMLBvWkEid2NNynrFTIQl1tPfuZ1VW125L4NrVCFS4/zBdlao?= =?us-ascii?Q?T3SGkr9WV+JFPU0wHdBETFeJcAb3O04o5mPKCxVPulYe4DNoa0NuqfqQ4bEw?= =?us-ascii?Q?JE5gT5qm3/byUm1iIx11U8Oi6YACEiP4xLSTetHzc5q433t5Pc877vcYemM1?= =?us-ascii?Q?3rzOTenx90HG0riCXYxudR97zywlZXbtipO43ZkseEkbteInwHvdR+lMzghW?= =?us-ascii?Q?GdbSwAf2xu6TdX7XMF9GjBk86nLgjKHKFzoxIXU9oWlZw1LN9bNJ7xRcTaRR?= =?us-ascii?Q?U7t59ttf30TGwsx2duy2nHx7nonMvlqdqfczz6aqL44ASkVw+0SWrSs9Wmz1?= =?us-ascii?Q?o+OAelRF3U5PuFzOzNDWp92NKn9VoUNcPhk0hTiOlOYIYb11KzfwLDPbQ86r?= =?us-ascii?Q?JkUmumMIO3Nv02usm4L3qeXEGvPf7fEGV8AzSgOVj/1NS/+fL1nIJOVA7w+j?= =?us-ascii?Q?i4Qb?= 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: 07 Jan 2021 18:51:51.7269 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: f06ac571-6422-4cb6-4c91-08d8b33d4bbd X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: xsBUfIwGxHKOGWpHRvL36uPlPrC/Hh4h5pHSZxO+X1SwRjoh8VwUa8l5ectPSPyOoqMVrFkEwVORkkto67UNLA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR12MB4987 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 Acked-by: Laszlo Ersek Signed-off-by: Tom Lendacky --- OvmfPkg/AmdSev/AmdSevX64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf | 2 +- OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf | 2 + OvmfPkg/Library/VmgExitLib/VmgExitLib.inf | 2 + OvmfPkg/Library/VmgExitLib/VmgExitVcHandler.c | 81 ++++++++= ++++++++++++ 6 files changed, 88 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index c4d93f39b9f1..dad8635c3388 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/SecMemEncryptSevLi= b.inf =20 [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index bfa9dd7cac1f..70ff2bcf2342 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -266,6 +266,7 @@ [LibraryClasses.common.SEC] CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SecPeiC= puExceptionHandlerLib.inf !endif VmgExitLib|OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf + MemEncryptSevLib|OvmfPkg/Library/BaseMemEncryptSevLib/SecMemEncryptSevLi= b.inf =20 [LibraryClasses.common.PEI_CORE] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf diff --git a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf b= /OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf index 8e3b8ddd5a95..f2e162d68076 100644 --- a/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.inf +++ b/OvmfPkg/Library/BaseMemEncryptSevLib/DxeMemEncryptSevLib.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..e6f6ea7972fd 100644 --- a/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf +++ b/OvmfPkg/Library/VmgExitLib/SecVmgExitLib.inf @@ -35,6 +35,8 @@ [LibraryClasses] BaseLib BaseMemoryLib DebugLib + LocalApicLib + 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.30.0