From nobody Fri Dec 19 07:23:03 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org ARC-Seal: i=1; a=rsa-sha256; t=1747156017; cv=none; d=zohomail.com; s=zohoarc; b=CXP4Gn9KRjwKASsepqv0yr4A8TUO/M0V0UoIdWGvKYd8GKz24htAiihUi/ogvpIXCeXDtYjdwPd4ZZDaZDlSR6bxUrqBs9d3Eh83moiqk6MNsuFAOmRD1uv2A4S6ODv7QtCPhYx7U7UVXvoDy1B5obh+VMs9WLU5MKDEKbsjTdU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747156017; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=tFKfUzszVh/xwE4DF75x7y3iV3k/7BaG2IaI1fkSePQ=; b=cLOBeVzsIA+xDdkR1RIX7tJ7j93sDGADUMU3iuARdZ0h2RWXAG8p18w/cnJnO6pb3A8gU3yhaqc7cwJL2EKp31DPnlgpgwP5FcR/kAtx9sOpemFL6OqZp18wJilmrwmDRDFEFtu6m2ldOlRbwphtnzD1p2YPx633S4RNYBxpfR4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1747156017841673.454736815618; Tue, 13 May 2025 10:06:57 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.983188.1369573 (Exim 4.92) (envelope-from ) id 1uEt5U-000504-M7; Tue, 13 May 2025 17:06:40 +0000 Received: by outflank-mailman (output) from mailman id 983188.1369573; Tue, 13 May 2025 17:06:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uEt5U-0004zt-Hd; Tue, 13 May 2025 17:06:40 +0000 Received: by outflank-mailman (input) for mailman id 983188; Tue, 13 May 2025 17:06:39 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uEt5T-0003Uz-1w for xen-devel@lists.xenproject.org; Tue, 13 May 2025 17:06:39 +0000 Received: from 7.mo581.mail-out.ovh.net (7.mo581.mail-out.ovh.net [46.105.43.131]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id a1530611-301c-11f0-9ffb-bf95429c2676; Tue, 13 May 2025 19:06:37 +0200 (CEST) Received: from director1.ghost.mail-out.ovh.net (unknown [10.108.25.156]) by mo581.mail-out.ovh.net (Postfix) with ESMTP id 4ZxjYm6MKXz1Fhd for ; Tue, 13 May 2025 17:06:36 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-v29lk (unknown [10.110.188.76]) by director1.ghost.mail-out.ovh.net (Postfix) with ESMTPS id C1C081FE80; Tue, 13 May 2025 17:06:35 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.105]) by ghost-submission-5b5ff79f4f-v29lk with ESMTPSA id eryDIBt8I2hUshgACLuduA (envelope-from ); Tue, 13 May 2025 17:06:35 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: a1530611-301c-11f0-9ffb-bf95429c2676 Authentication-Results: garm.ovh; auth=pass (GARM-105G0062e7951fd-12e2-49b8-a10e-061233634830, 0F27B6D195039ACFBDF5EC7F2AC12BEA7E98F15C) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.181.178 From: Sergii Dmytruk To: xen-devel@lists.xenproject.org Cc: "Daniel P. Smith" , Ross Philipson , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , trenchboot-devel@googlegroups.com Subject: [PATCH v2 05/22] x86/boot/slaunch-early: early TXT checks and boot data retrieval Date: Tue, 13 May 2025 20:05:42 +0300 Message-ID: X-Mailer: git-send-email 2.49.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Ovh-Tracer-Id: 8943022961074877596 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdeftdegieejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecuhedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvvefufffkofgjfhgggfestdekredtredttdenucfhrhhomhepufgvrhhgihhiucffmhihthhruhhkuceoshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmqeenucggtffrrghtthgvrhhnpefhheefheduieelieekfffgfffgfedutdevleevvdfhfffgledvgfdtuddtheefieenucfkphepuddvjedrtddrtddruddpudejiedrudduuddrudekuddrudejkedpfeejrdehledrudegvddruddtheenucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepihhnvghtpeduvdejrddtrddtrddupdhmrghilhhfrhhomhepshgvrhhgihhirdgumhihthhruhhkseefmhguvggsrdgtohhmpdhnsggprhgtphhtthhopedupdhrtghpthhtohepgigvnhdquggvvhgvlheslhhishhtshdrgigvnhhprhhojhgvtghtrdhorhhgpdfovfetjfhoshhtpehmohehkedumgdpmhhouggvpehsmhhtphhouhht DKIM-Signature: a=rsa-sha256; bh=tFKfUzszVh/xwE4DF75x7y3iV3k/7BaG2IaI1fkSePQ=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1747155996; v=1; b=kA2RD/zQxREyvarndY+ACW5/XynAiaUxCEKShSot9JONW+eum6rTMfs5X1Z9PfaXnNZi2cKy amSc/q7Sf7bHxU3yHNAxWWQzNUnh4/MFhIN0RxNh1X8rbou8nkIlBwWPh+P91gSpRIP1Ci37olM gu0D1rRPkZesm7OOSAefom1czrSnsQ28BMvxXXjd36D+eb58SJX7lzBkyUX5sUYcHSD2FcMjDSN ZBKuVG2j3fWS6AYasmCNMJwNZp2uTG2doTDOPZPWOpAl9B3Mh3Ij3HYHTSXQZThh0tEllnnVFtB hXgo1P11mDZqEqbRaat9OUi5JljPgAxsz50tV/1tG2rYw== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1747156019797019000 Content-Type: text/plain; charset="utf-8" From: Krystian Hebel The tests validate that important parts of memory are protected against DMA attacks, including Xen and MBI. Modules can be tested later, when it is possible to report issues to a user before invoking TXT reset. TPM event log validation is temporarily disabled due to an issue with its allocation by bootloader (GRUB) which will need to be modified to address this. Ultimately event log will also have to be validated early as it is used immediately after these tests to hold MBI measurements. See larger comment in txt_verify_pmr_ranges(). Signed-off-by: Krystian Hebel Signed-off-by: Sergii Dmytruk --- xen/arch/x86/boot/slaunch-early.c | 6 ++ xen/arch/x86/include/asm/intel-txt.h | 111 +++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) diff --git a/xen/arch/x86/boot/slaunch-early.c b/xen/arch/x86/boot/slaunch-= early.c index 48776ef559..b6f6deedc9 100644 --- a/xen/arch/x86/boot/slaunch-early.c +++ b/xen/arch/x86/boot/slaunch-early.c @@ -22,10 +22,13 @@ void asmlinkage slaunch_early_init(uint32_t load_base_a= ddr, void *txt_heap; struct txt_os_mle_data *os_mle; struct slr_table *slrt; + struct txt_os_sinit_data *os_sinit; struct slr_entry_intel_info *intel_info; + uint32_t size =3D tgt_end_addr - tgt_base_addr; =20 txt_heap =3D txt_init(); os_mle =3D txt_os_mle_data_start(txt_heap); + os_sinit =3D txt_os_sinit_data_start(txt_heap); =20 result->slrt_pa =3D os_mle->slrt; result->mbi_pa =3D 0; @@ -38,4 +41,7 @@ void asmlinkage slaunch_early_init(uint32_t load_base_add= r, return; =20 result->mbi_pa =3D intel_info->boot_params_base; + + txt_verify_pmr_ranges(os_mle, os_sinit, intel_info, + load_base_addr, tgt_base_addr, size); } diff --git a/xen/arch/x86/include/asm/intel-txt.h b/xen/arch/x86/include/as= m/intel-txt.h index 7a665b7cc3..339c29ebef 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -84,6 +84,8 @@ =20 #ifndef __ASSEMBLY__ =20 +#include + /* Need to differentiate between pre- and post paging enabled. */ #ifdef __EARLY_SLAUNCH__ #include @@ -288,6 +290,115 @@ static inline void *txt_init(void) return txt_heap; } =20 +static inline int is_in_pmr(struct txt_os_sinit_data *os_sinit, uint64_t b= ase, + uint32_t size, int check_high) +{ + /* Check for size overflow. */ + if ( base + size < base ) + txt_reset(SLAUNCH_ERROR_INTEGER_OVERFLOW); + + /* Low range always starts at 0, so its size is also end address. */ + if ( base >=3D os_sinit->vtd_pmr_lo_base && + base + size <=3D os_sinit->vtd_pmr_lo_size ) + return 1; + + if ( check_high && os_sinit->vtd_pmr_hi_size !=3D 0 ) + { + if ( os_sinit->vtd_pmr_hi_base + os_sinit->vtd_pmr_hi_size < + os_sinit->vtd_pmr_hi_size ) + txt_reset(SLAUNCH_ERROR_INTEGER_OVERFLOW); + if ( base >=3D os_sinit->vtd_pmr_hi_base && + base + size <=3D os_sinit->vtd_pmr_hi_base + + os_sinit->vtd_pmr_hi_size ) + return 1; + } + + return 0; +} + +static inline void txt_verify_pmr_ranges(struct txt_os_mle_data *os_mle, + struct txt_os_sinit_data *os_sini= t, + struct slr_entry_intel_info *info, + uint32_t load_base_addr, + uint32_t tgt_base_addr, + uint32_t xen_size) +{ + int check_high_pmr =3D 0; + + /* Verify the value of the low PMR base. It should always be 0. */ + if ( os_sinit->vtd_pmr_lo_base !=3D 0 ) + txt_reset(SLAUNCH_ERROR_LO_PMR_BASE); + + /* + * Low PMR size should not be 0 on current platforms. There is an ongo= ing + * transition to TPR-based DMA protection instead of PMR-based; this i= s not + * yet supported by the code. + */ + if ( os_sinit->vtd_pmr_lo_size =3D=3D 0 ) + txt_reset(SLAUNCH_ERROR_LO_PMR_SIZE); + + /* Check if regions overlap. Treat regions with no hole between as err= or. */ + if ( os_sinit->vtd_pmr_hi_size !=3D 0 && + os_sinit->vtd_pmr_hi_base <=3D os_sinit->vtd_pmr_lo_size ) + txt_reset(SLAUNCH_ERROR_HI_PMR_BASE); + + /* All regions accessed by 32b code must be below 4G. */ + if ( os_sinit->vtd_pmr_hi_base + os_sinit->vtd_pmr_hi_size <=3D + 0x100000000ULL ) + check_high_pmr =3D 1; + + /* + * ACM checks that TXT heap and MLE memory is protected against DMA. W= e have + * to check if MBI and whole Xen memory is protected. The latter is do= ne in + * case bootloader failed to set whole image as MLE and to make sure t= hat + * both pre- and post-relocation code is protected. + */ + + /* Check if all of Xen before relocation is covered by PMR. */ + if ( !is_in_pmr(os_sinit, load_base_addr, xen_size, check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_LO_PMR_MLE); + + /* Check if all of Xen after relocation is covered by PMR. */ + if ( load_base_addr !=3D tgt_base_addr && + !is_in_pmr(os_sinit, tgt_base_addr, xen_size, check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_LO_PMR_MLE); + + /* + * If present, check that MBI is covered by PMR. MBI starts with 'uint= 32_t + * total_size'. + */ + if ( info->boot_params_base !=3D 0 && + !is_in_pmr(os_sinit, info->boot_params_base, + *(uint32_t *)(uintptr_t)info->boot_params_base, + check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_BUFFER_BEYOND_PMR); + + /* Check if TPM event log (if present) is covered by PMR. */ + /* + * FIXME: currently commented out as GRUB allocates it in a hole betwe= en + * PMR and reserved RAM, due to 2MB resolution of PMR. There are no ot= her + * easy-to-use DMA protection mechanisms that would allow to protect t= hat + * part of memory. TPR (TXT DMA Protection Range) gives 1MB resolution= , but + * it still wouldn't be enough. + * + * One possible solution would be for GRUB to allocate log at lower ad= dress, + * but this would further increase memory space fragmentation. Another + * option is to align PMR up instead of down, making PMR cover part of + * reserved region, but it is unclear what the consequences may be. + * + * In tboot this issue was resolved by reserving leftover chunks of me= mory + * in e820 and/or UEFI memory map. This is also a valid solution, but = would + * require more changes to GRUB than the ones listed above, as event l= og is + * allocated much earlier than PMRs. + */ + /* + if ( os_mle->evtlog_addr !=3D 0 && os_mle->evtlog_size !=3D 0 && + !is_in_pmr(os_sinit, os_mle->evtlog_addr, os_mle->evtlog_size, + check_high_pmr) ) + txt_reset(SLAUNCH_ERROR_BUFFER_BEYOND_PMR); + */ +} + #endif /* __ASSEMBLY__ */ =20 #endif /* ASM__X86__INTEL_TXT_H */ --=20 2.49.0