From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (NAM10-MW2-obe.outbound.protection.outlook.com [40.107.94.70]) by mx.groups.io with SMTP id smtpd.web09.475.1609968272496316535 for ; Wed, 06 Jan 2021 13:24:32 -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=V8TcjE5Q; 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.94.70, mailfrom: thomas.lendacky@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=aoD/ackcBAtBuZ0rxCE1IsQN859LRunqNh7HTzKFnFyfgA60iW8aQPUx4eV5if1jJcbkFDn/Hzsrd72FPiWMlCyEg/ooBmm8a08jzSEw2WHDTS2aRqUXSMS9p2dfKRLIFOeWCEgQ/KtSOpzcQDaKFYC3ZorYfU1DjW/zG/jE3n8CloL49wNhGNlYEcp9ZzJWB7tgS9pZS68omSRjU+r4Au2lJnIRMYMoNv8yjD30mQoWIYBcpq+nuBCZ6hquFViqBwGO5wyQOh5KA+VvI+rjyTIJb0UxpxoQEnZKPqrGLLLdVSs3A5nle4Jms18jtDHcsFvCS/cMPZawX2++5qabkg== 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=EgKAq0MI28MSCUbfA7wXxXrwh5l1/49LVbEMuFwz7zU7zbHnw+GuHQdC3TJ3gbKhtQCdrO8FUe1znjbIcoHkRyDHq1Z14A0WtzXOOddTN5xHZitzfQTAYGVolF/aJAVfpkFpYQGI4fcSXNIZcKWXT1iVCBjQTH/bBlvaYYS6BpoOO2sT+ukGMOJCrPHUUro6pDOQnnzqHdKuVsLTK6j/jg9JycHR9W0hlKSxVB13fViG8MfcpShU6ybL0mgU1m/h7ys1zoxRo146NXAJGIJU250k1OsTlogdPh4sDrw7MD7LzQTMRTwjci4P0of1XQ843qHzcr2pHzjxOZd2V4hzpA== 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=V8TcjE5Qv5OpkBivEpmhB4o0keaZe0zkjeZH7tn9f/NHeg3GMwE2kqcr/6VTxQVrPLy4piP8SwrB7Ztrj8aWUC0O6shJjjJOKGjnZBeVoeDNsH31ZZ6Pjfmp+UnQ2gINp10G8/V74jFbmLvj5EohY4rwGndTH23H1VVjTJHWBl8= 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 DM5PR12MB1259.namprd12.prod.outlook.com (2603:10b6:3:75::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3742.6; Wed, 6 Jan 2021 21:24:30 +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; Wed, 6 Jan 2021 21:24:30 +0000 From: "Lendacky, Thomas" To: devel@edk2.groups.io CC: Brijesh Singh , James Bottomley , Jordan Justen , Laszlo Ersek , Ard Biesheuvel Subject: [PATCH v2 15/15] OvfmPkg/VmgExitLib: Validate #VC MMIO is to un-encrypted memory Date: Wed, 6 Jan 2021 15:21:41 -0600 Message-ID: X-Mailer: git-send-email 2.30.0 In-Reply-To: References: X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: SN6PR08CA0030.namprd08.prod.outlook.com (2603:10b6:805:66::43) 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 SN6PR08CA0030.namprd08.prod.outlook.com (2603:10b6:805:66::43) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3742.6 via Frontend Transport; Wed, 6 Jan 2021 21:24:29 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: c4dce191-073e-478f-7717-08d8b2897431 X-MS-TrafficTypeDiagnostic: DM5PR12MB1259: 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: 9JnSKGohk2glCN+vOjgUz6rQa5Z3XwUvfFBm905uWoEKCTGLBRXPFkTihUNUFll8raeuNJE//szgTboK8rJ0lWHACzyLKg//B74BrRgXWZgwiw8mFw/cNJeCCFJ1FXg+kqT8VC1NCN5Bdu54s1HfSCimRcbr+PtaZbl1P+6g3aPrrN3cYbSiN5whhCzIGOKc46xby/GAlD3xff33TyAaqoFPyOuU6MopDF98hOHvn8QrGXZ9zgOT1n2xYuZMNP3dil8hGhOqxc5PmLz6Zz++FGXW3HnJZE7GO6EWxNvl/4S3pUZEdSMoDLpPT2iX/Y3AaMqwc7ymkvxqEDbyn6a8VUr6KhWFaL4UfKrtT/6aoARON8WloKcv5h0i1l4fotMxJHN3vDXhp+jQOePDjAsyQLvxKSQhVRmfXwfI56j5uLhUqyIxh+OVTyU9RF1KaCCbwhIqLd5BrR4xGkkUQZ7K8w== 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)(396003)(39860400002)(366004)(136003)(376002)(346002)(86362001)(2616005)(66946007)(15650500001)(6486002)(956004)(6916009)(66556008)(186003)(16526019)(66476007)(26005)(4326008)(83380400001)(45954011)(5660300002)(8676002)(36756003)(2906002)(52116002)(7696005)(19627235002)(6666004)(316002)(966005)(478600001)(8936002)(54906003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?QtGTK4HFOf4mXdD4XDm3SJXIy4q4cNRT6UnrVNgQwXIJiBJLoLzRnHj9Qcn9?= =?us-ascii?Q?cMbMFIk2mwopBonGwilBkSphfLQ7Egjz2ptfp3VnSkicODbIQQjZQxliJjSh?= =?us-ascii?Q?bChWBChFAaxMp3Sb8z4IbzaQwCx71Jc8P3vb6M16FgQZxDAFye3BqoK7qEDJ?= =?us-ascii?Q?aVbhsIzt9sAlXTlcpTOfKnuGcSXeK+EUvSXQCMYJV+I39TNb3ahkqwbytKgp?= =?us-ascii?Q?sc5A8B6ZD2ZIOsIe0F9fbhbgdNNVDrjzC5B30ED/1HPK9rL/GWN4i9Q5A2o1?= =?us-ascii?Q?8BVzRbtakOAuVQsEU2+wZZUAYmpsal7vgbRVYKVJoqgxcYlQpmtxenidD5QP?= =?us-ascii?Q?mMra7AXoT5XoIiXP9VqbwqfNth+cdRFRFeraKl1VAzYxfayYHfuij6wSOe04?= =?us-ascii?Q?1SMjeJ0Nms8bWPwBewFJW4bIsXZvqUODDoTbFg85U43SKeqFcQVdEVIA/IHA?= =?us-ascii?Q?Qn0v0bEhKgknljqRXJb+bDK1ko7NU7MFPji0I4C6bDuhn2sPwu358IWUUEI+?= =?us-ascii?Q?bdjk7arR1nw38Nx9yxeKIy3dPcDJBBRR0O/TCUd9zo8UrUh9MZqTlE5SkHgw?= =?us-ascii?Q?1Vx6wcfUXQAPerXIK2RetNiFRErNy+e1DUJ4BzdD5RpX+aV9fYfjz4qBVPXu?= =?us-ascii?Q?h0lm/o1UmwNEjJFeM8KvuwxEhfRNQxOUr39XjugGttdFZ2TIeS/dx17uDjFI?= =?us-ascii?Q?+PZmfrQtuVUJUkaBShKTMRfR6ndH5tYbeeuc0kD9djFNfEhAgEWpB8FjsmkG?= =?us-ascii?Q?sdncNXeBDIEZuijEW0jjGZj7Vwg4gGRwk7vkS3uo9zykG9SOpxzILJ/uCCCl?= =?us-ascii?Q?Is9hQ/o0ZDh1maY49WpGWAqzqExAX6cjb+pnQ+qaM19TBCAJNH58xY3BtT71?= =?us-ascii?Q?Zs+ujKbeA1rfTusHHV6V+04LkC5m27B75JOcoFQrfcTJili7j5tQgLkdPI33?= =?us-ascii?Q?5OMTrl3ilnAjQlxBjWD5LNJWyoIBIjKpu+VhOseGcVockqYMcFIDJ9Mk9+wM?= =?us-ascii?Q?n5SI?= 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: 06 Jan 2021 21:24:30.1418 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-Network-Message-Id: c4dce191-073e-478f-7717-08d8b2897431 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 2p2fUPivR3+1qb+MubqLefW5aV3vEyNetPieVY9zCE6OWPVjsUlncqUAwYWAJ84JHkD2fv2tBi5UHT3Fx4V6+Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM5PR12MB1259 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