From nobody Thu Oct 30 18:37:27 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 header.i=yann.sionneau@vates.tech; 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; dmarc=pass(p=reject dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1753366094; cv=none; d=zohomail.com; s=zohoarc; b=TS4AZfGZEIkzId7fepo7K0ZZIF71rPsd8u9iZfNQZtCaIWJskLBX3kEae7mqTVkRcfe4nH2mPaerzTDHFe95OITtyU9wf44JKclTBhFoonk+wKOnt4bMudsCl/hAiojGJslkXz3d9S1xCQzR5/HXBy9SYUEpUhPKLmZ8C2TTsJo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1753366094; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=cia2BzDWY4ebE/PW5ST0QN+7zrDvuTDanOKqXxDfmmM=; b=HA1FDcZTvP5myXllV31JPam+XNKzK4+/bScCl5y84SGAvcWa+wJWvTB8JjA1o8T0w/iIUZaqtqlqYI0xr7rofANq8WB7PrR5qF77Jw8QRchs/q5gxYRrb7FcHrMENvxbpI+QjtuMGA8u7L6VzCC4+ihNsbIDsWWSxD2+Qo/qUAc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=yann.sionneau@vates.tech; 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; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1753366094644739.0092575154335; Thu, 24 Jul 2025 07:08:14 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1056121.1424268 (Exim 4.92) (envelope-from ) id 1uewby-00056L-C0; Thu, 24 Jul 2025 14:07:54 +0000 Received: by outflank-mailman (output) from mailman id 1056121.1424268; Thu, 24 Jul 2025 14:07:54 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1uewby-00056E-7F; Thu, 24 Jul 2025 14:07:54 +0000 Received: by outflank-mailman (input) for mailman id 1056121; Thu, 24 Jul 2025 14:07:53 +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 1uewbx-000567-4z for xen-devel@lists.xenproject.org; Thu, 24 Jul 2025 14:07:53 +0000 Received: from mail180-9.suw31.mandrillapp.com (mail180-9.suw31.mandrillapp.com [198.2.180.9]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 94dfa9c7-6897-11f0-b895-0df219b8e170; Thu, 24 Jul 2025 16:07:50 +0200 (CEST) Received: from pmta11.mandrill.prod.suw01.rsglab.com (localhost [127.0.0.1]) by mail180-9.suw31.mandrillapp.com (Mailchimp) with ESMTP id 4bntBD6Qx8zK5vnMS for ; Thu, 24 Jul 2025 14:07:48 +0000 (GMT) Received: from [37.26.189.201] by mandrillapp.com id 37a91361c26a4bb59f27d23fc7416fe2; Thu, 24 Jul 2025 14:07:48 +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: 94dfa9c7-6897-11f0-b895-0df219b8e170 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; s=mte1; t=1753366068; x=1753636068; bh=cia2BzDWY4ebE/PW5ST0QN+7zrDvuTDanOKqXxDfmmM=; h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version: Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From; b=SFU4JJFUmuL9NrNZ+CNA6wB68x2sB65cWCvKDM2AE6ru/EBZpW4z000y5T/+A8pYA EPx0JL+iwXdJJZJKmAIqJnG9EtFK963n0QWCnYpYk1HiPwVzzSywK7yLBANe1oJRAj ldJ1B1AxP0hS/ea62VVhyNbrUzAobhym8KAz5khQxXs0LnVUNRHevXCaHlS/IHKPtc 9vI6bRL7XTxNBWfXY5F64HSYmAoEbQvSnTp5Nxq5mnxTcSnxx/SThUs9tbEMvQlwkv gy/S8hxC9tuYEMHhkgDAkf5fdRN7X8P81wbBcPMq8agUT9Z4d2/EPmv8Iq1ikHRzpC JAFmCDsEwoSwg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; s=mte1; t=1753366068; x=1753626568; i=yann.sionneau@vates.tech; bh=cia2BzDWY4ebE/PW5ST0QN+7zrDvuTDanOKqXxDfmmM=; h=From:Subject:To:Cc:Message-Id:Feedback-ID:Date:MIME-Version: Content-Type:Content-Transfer-Encoding:CC:Date:Subject:From; b=gDTDb7xTBilTejOiQLUWQzEAVuwvaGJLUmAXYf0+vggoqDgfXRrcFffa8Io+TPOYB RQtoI/xE5uo5mwgfepVzZgYBScIWRONvv5a+wl5xW2lH8bq9Qdo1X0uzZhuR3mr8xu aG16mga5+nS6k0UzLTbxgKoKfS7zC+EinXCUcyHam5PcYZY523Eema9xWgJSdK0an3 34sfAM93s2Nfrhd5Z1AVYnJXihoEMACmbB8J2K6GB9LdVuiBl0reDbn176K6Uml6Cd JmigqyVZgYi5tzH8qv43OtelH/krgpG64EIGGG8Bcy7mYXWt7f4WgKp5Ori6XhXgvT Ty9dIalQHBsww== From: "Yann Sionneau" Subject: =?utf-8?Q?[PATCH=20v2]=20xen/x86:=20fix=20xen.efi=20boot=20crash=20from=20some=20bootloaders?= X-Mailer: git-send-email 2.43.0 X-Bm-Disclaimer: Yes X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1753366067577 To: xen-devel@lists.xenproject.org Cc: "Yann Sionneau" , "Jan Beulich" , "Andrew Cooper" , "=?utf-8?Q?Roger=20Pau=20Monn=C3=A9?=" , "Anthony PERARD" , "Michal Orzel" , "Julien Grall" , "Stefano Stabellini" Message-Id: <20250724140731.1502774-1-yann.sionneau@vates.tech> X-Native-Encoded: 1 X-Report-Abuse: =?UTF-8?Q?Please=20forward=20a=20copy=20of=20this=20message,=20including=20all=20headers,=20to=20abuse@mandrill.com.=20You=20can=20also=20report=20abuse=20here:=20https://mandrillapp.com/contact/abuse=3Fid=3D30504962.37a91361c26a4bb59f27d23fc7416fe2?= X-Mandrill-User: md_30504962 Feedback-ID: 30504962:30504962.20250724:md Date: Thu, 24 Jul 2025 14:07:48 +0000 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @mandrillapp.com) (identity yann.sionneau@vates.tech) X-ZM-MESSAGEID: 1753366096960116600 Content-Type: text/plain; charset="utf-8" xen.efi PE does not boot when loaded from shim or some patched downstream grub2. What happens is the bootloader would honour the MEM_DISCARDABLE flag of the .reloc section meaning it would not load its content into memory. But Xen is parsing the .reloc section content twice at boot: * https://elixir.bootlin.com/xen/v4.20.1/source/xen/common/efi/boot.c#L1362 * https://elixir.bootlin.com/xen/v4.20.1/source/xen/arch/x86/efi/efi-boot.h= #L237 Therefore it would crash with the following message: "Unsupported relocation type" as reported there: * https://github.com/QubesOS/qubes-issues/issues/8206#issuecomment-26190488= 38 * https://lore.kernel.org/xen-devel/7e039262-1f54-46e1-8f70-ac3f03607d5a@su= se.com/T/#me122b9e6c27cd98db917da2c9f67e74a2c6ad7a5 This commit adds a small C host tool named keeprelocs that is called after xen.efi is produced by the build system in order to remove this bit from its .reloc section header. Signed-off-by: Yann Sionneau --- Changes since v1: - use xen coding style instead of Linux kernel one - use void * to store the return value from mmap() - PE file is passed as non-optional argument instead of -i FILE - use bool instead of int type for "quiet" flag - remove useless break after return - add missing 0x before %08x conversion specifier - add SPDX header - remove DEBUG stuff - improve opt_hdr_size checks - removed useless tools_keeprelocs Makefile target - fixed -I include path for keeprelocs tool: use $(srctree) - use memcmp instead of strncmp - produce an intermediate xen.efi.1 before running keeprelocs so that an interrupted build would not end up having a bad xen.efi (with MEM_DISCARDABLE flag in .reloc section). In other words: make sure the final xen.efi is produced only after all modifications are done. Link to v1: https://lore.kernel.org/xen-devel/20250723135620.1327914-1-yann= .sionneau@vates.tech/ --- xen/arch/x86/Makefile | 6 +- xen/tools/Makefile | 3 + xen/tools/keeprelocs.c | 165 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 xen/tools/keeprelocs.c diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index ce724a9daa..91af6ae214 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -232,10 +232,12 @@ endif $(MAKE) $(build)=3D$(@D) .$(@F).1r.o .$(@F).1s.o $(LD) $(call EFI_LDFLAGS,$(VIRT_BASE)) -T $(obj)/efi.lds $< \ $(dot-target).1r.o $(dot-target).1s.o $(orphan-handling-y) \ - $(note_file_option) -o $@ - $(NM) -pa --format=3Dsysv $@ \ + $(note_file_option) -o $@.1 + $(NM) -pa --format=3Dsysv $@.1 \ | $(objtree)/tools/symbols --all-symbols --xensyms --sysv --sort \ > $@.map + $(objtree)/tools/keeprelocs -q $@.1 + mv $@.1 $@ ifeq ($(CONFIG_DEBUG_INFO),y) $(if $(filter --strip-debug,$(EFI_LDFLAGS)),:$(space))$(OBJCOPY) -O elf64= -x86-64 $@ $@.elf endif diff --git a/xen/tools/Makefile b/xen/tools/Makefile index a5078b7cb8..620063ab1e 100644 --- a/xen/tools/Makefile +++ b/xen/tools/Makefile @@ -1,2 +1,5 @@ hostprogs-always-y +=3D symbols hostprogs-always-y +=3D fixdep +hostprogs-always-$(XEN_BUILD_PE) +=3D keeprelocs +# next line is to allow including include/efi/pe.h +HOSTCFLAGS_keeprelocs.o :=3D -I $(srctree)/include \ No newline at end of file diff --git a/xen/tools/keeprelocs.c b/xen/tools/keeprelocs.c new file mode 100644 index 0000000000..284378564a --- /dev/null +++ b/xen/tools/keeprelocs.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void print_usage(const char *name) +{ + printf("%s: [-q] [-h] xen.efi\n", name); +} + +static int get_minimum_opt_hdr_size(uint16_t opt_hdr_magic) +{ + switch ( opt_hdr_magic ) + { + case PE_OPT_MAGIC_PE32: + return sizeof(struct pe32_opt_hdr); + case PE_OPT_MAGIC_PE32PLUS: + return sizeof(struct pe32plus_opt_hdr); + default: + return -1; + } +} + +int main(int argc, char **argv) +{ + char *filename =3D NULL; + int fd; + void *mem; + struct stat st; + off_t len; + int ret; + struct mz_hdr *mz; + struct pe_hdr *pe; + int opt; + const char *prog_name =3D argv[0]; + bool quiet =3D false; + int min_opt_hdr_size; + unsigned int section_id; + + while ( (opt =3D getopt(argc, argv, ":qh")) !=3D -1 ) + { + switch ( opt ) + { + case 'q': + quiet =3D true; + break; + case 'h': + print_usage(prog_name); + return 0; + case '?': + default: + print_usage(prog_name); + return -1; + } + } + + if ( optind < argc ) + filename =3D argv[optind++]; + else + { + printf("Error: you must provide the PE file name as first and only= non-optional argument\n"); + return -1; + } + + if ( optind !=3D argc ) + { + printf("Only one non-optional argument should be supplied: the PE = file name\n"); + return -1; + } + + fd =3D open(filename, O_RDWR); + if ( fd < 0 ) + { + printf("Could not open file %s: %s\n", filename, strerror(errno)); + return -1; + } + + ret =3D fstat(fd, &st); + if ( ret < 0 ) + { + perror("Error while getting PE file length"); + return -1; + } + + len =3D st.st_size; + mem =3D mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + if ( mem =3D=3D MAP_FAILED ) + { + perror("Failed to mmap PE file"); + return -1; + } + + mz =3D mem; + if ( mz->magic !=3D MZ_MAGIC ) + { + printf("file has incorrect MZ header 0x%02x instead of 0x5a4d\n", + mz->magic); + return -1; + } + + pe =3D mem + mz->peaddr; + if ( memcmp((char *)&pe->magic, "PE\0\0", 4) ) + { + printf("file has incorrect PE header magic 0x%08x instead of 0x000= 04550\n", + pe->magic); + return -1; + } + + if ( pe->opt_hdr_size < 2 ) + { + printf("file has too small OptionalHeaderSize: %d\n", pe->opt_hdr_= size); + return -1; + } + + /* Compute minimum optional header size, based on its + * first field (uint16_t magic). + */ + min_opt_hdr_size =3D get_minimum_opt_hdr_size(*(uint16_t *)((void *)pe + + sizeof(*pe))); + if ( min_opt_hdr_size < 0 ) + { + printf("Incorrect binary type, should be PE32 or PE32+\n"); + return -1; + } + + if ( pe->opt_hdr_size < min_opt_hdr_size ) + { + printf("file has too small OptionalHeaderSize: %d\n", pe->opt_hdr_= size); + return -1; + } + + struct section_header *section =3D (struct section_header *)((uint8_t = *)pe + + sizeof(*pe) + pe->opt_hdr_size); + for ( section_id =3D 0; section_id < pe->sections; section_id++, secti= on++ ) + { + if ( memcmp(section->name, ".reloc", strlen(".reloc") + 1) ) + continue; + + if ( !quiet ) + printf(".reloc section characteristics: %08x\n", section->flag= s); + if ( section->flags & IMAGE_SCN_MEM_DISCARDABLE ) + { + if ( !quiet ) + printf("MEM_DISCARDABLE flag found! Dropping it.\n"); + section->flags &=3D ~(IMAGE_SCN_MEM_DISCARDABLE); + } + } + + munmap(mem, len); + close(fd); + + if ( !quiet ) + printf("Ok!\n"); + return 0; +} --=20 2.43.0 Yann Sionneau | Vates XCP-ng Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech