From nobody Fri Oct 31 16:01:16 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=1748611152; cv=none; d=zohomail.com; s=zohoarc; b=ewY+XGinE9w6RgpVZPBeAvEV7/1Y9i4R1chb/OnKGRLKaWx5sM3NwfO74RurgfR7DdKsZRcHksbowvy8covvb3vSRersKmRrqPxwqr8Rbvjx4SNBVct9/QLL6oNLc2TQVEVClyhnmlposQZoaPq4uciHrI7JiRk+r8rrmniROu8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1748611152; 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=Ze8+L6G+0Rc7+4Bq+m7/6vFCoR62w3qclGgLacvIoZA=; b=mxYUmo1i2htgI9v4sQtTs5MYcD7xZqk0+9o8bomGnj7R+VyqQJd0e4G6D+FMSE+RfUhiMSNXkuuy9aBg9Mt+lqandB/FrztVOuX0s8KqWWXuM4mmGTHZPpGRoGIKdDY+otQWx7uGdcoOKR97n2rUg2MdT2liNuRGBrsAXcMpmv4= 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 1748611152142366.7503177071293; Fri, 30 May 2025 06:19:12 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1000936.1381155 (Exim 4.92) (envelope-from ) id 1uKzdI-0001CW-E4; Fri, 30 May 2025 13:18:48 +0000 Received: by outflank-mailman (output) from mailman id 1000936.1381155; Fri, 30 May 2025 13:18:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uKzdI-0001CJ-Ad; Fri, 30 May 2025 13:18:48 +0000 Received: by outflank-mailman (input) for mailman id 1000936; Fri, 30 May 2025 13:18:47 +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 1uKzdG-0000ql-U2 for xen-devel@lists.xenproject.org; Fri, 30 May 2025 13:18:46 +0000 Received: from 10.mo583.mail-out.ovh.net (10.mo583.mail-out.ovh.net [46.105.52.148]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9d18b53d-3d58-11f0-b894-0df219b8e170; Fri, 30 May 2025 15:18:45 +0200 (CEST) Received: from director5.ghost.mail-out.ovh.net (unknown [10.109.176.202]) by mo583.mail-out.ovh.net (Postfix) with ESMTP id 4b83j06CYsz1kgY for ; Fri, 30 May 2025 13:18:44 +0000 (UTC) Received: from ghost-submission-5b5ff79f4f-r8s5j (unknown [10.110.168.204]) by director5.ghost.mail-out.ovh.net (Postfix) with ESMTPS id B94B4100223; Fri, 30 May 2025 13:18:43 +0000 (UTC) Received: from 3mdeb.com ([37.59.142.111]) by ghost-submission-5b5ff79f4f-r8s5j with ESMTPSA id rs9PIzOwOWjQtgAAgydd6Q (envelope-from ); Fri, 30 May 2025 13:18:43 +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: 9d18b53d-3d58-11f0-b894-0df219b8e170 Authentication-Results: garm.ovh; auth=pass (GARM-111S0054675508b-6510-4009-9374-a7b742f4e717, A4E380CC922F0B59227EC5DCC46884561651840B) smtp.auth=sergii.dmytruk@3mdeb.com X-OVh-ClientIp: 176.111.184.221 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 v3 05/22] x86/boot/slaunch-early: early TXT checks and boot data retrieval Date: Fri, 30 May 2025 16:17:47 +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: 12696773251544298652 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtddtgddvleduudculddtuddrgeefvddrtddtmdcutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjughrpefhvfevufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpefuvghrghhiihcuffhmhihtrhhukhcuoehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomheqnecuggftrfgrthhtvghrnhephfehfeehudeileeikeffgfffgfefuddtveelvedvhfffgfelvdfgtddutdehfeeinecukfhppeduvdejrddtrddtrddupddujeeirdduuddurddukeegrddvvddupdefjedrheelrddugedvrdduuddunecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepuddvjedrtddrtddruddpmhgrihhlfhhrohhmpehsvghrghhiihdrughmhihtrhhukhesfehmuggvsgdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopeigvghnqdguvghvvghlsehlihhsthhsrdigvghnphhrohhjvggtthdrohhrghdpoffvtefjohhsthepmhhoheekfegmpdhmohguvgepshhmthhpohhuth DKIM-Signature: a=rsa-sha256; bh=Ze8+L6G+0Rc7+4Bq+m7/6vFCoR62w3qclGgLacvIoZA=; c=relaxed/relaxed; d=3mdeb.com; h=From; s=ovhmo3617313-selector1; t=1748611124; v=1; b=eHQo6MMWNilw9KMr/5ps9HwV90sMmmQb4iCsqFYY6RaZIbnl6BYqwYk2ch/L+oVHP4Cs+DGj BRDKLlcBdEXL0aviHBoLHwJ5XRo+yzbyPAMzQvYCcz1tTH9xMgOh5L0xB+OWP2A8pHAyCYKM4M9 yEIJzoYaZWZH90ES0jz39TDIYF0uayV6RK2cU/oBe9o4DnAsvqvukBd4Jbtv0J9CijBkyNsqphN +uYQHoJE5TLiETBh3xa7cCZwUjKHdEAGfOk9yy5IdF0Y9tyEUj1dOpW4LlEAnS1yCeh8MrJkxDM N82/v94/hsyo4IMycSoccIQppINRE479nyELIOzOG3XjA== X-ZohoMail-DKIM: pass (identity @3mdeb.com) X-ZM-MESSAGEID: 1748611154204116600 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 | 112 +++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/xen/arch/x86/boot/slaunch-early.c b/xen/arch/x86/boot/slaunch-= early.c index c9d364bcd5..662144e42f 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; const struct txt_os_mle_data *os_mle; const struct slr_table *slrt; + const struct txt_os_sinit_data *os_sinit; const 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 7658457e9d..122b4293ea 100644 --- a/xen/arch/x86/include/asm/intel-txt.h +++ b/xen/arch/x86/include/asm/intel-txt.h @@ -93,6 +93,8 @@ =20 #ifndef __ASSEMBLY__ =20 +#include + /* Need to differentiate between pre- and post paging enabled. */ #ifdef __EARLY_SLAUNCH__ #include @@ -308,6 +310,116 @@ static inline void *txt_init(void) return txt_heap; } =20 +static inline int is_in_pmr(const struct txt_os_sinit_data *os_sinit, + uint64_t base, 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( + const struct txt_os_mle_data *os_mle, + const struct txt_os_sinit_data *os_sinit, + const 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 /* X86_INTEL_TXT_H */ --=20 2.49.0