Received: by 2002:a05:7412:31a9:b0:e2:908c:2ebd with SMTP id et41csp2453544rdb; Tue, 12 Sep 2023 02:15:49 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH6ZqlEg3wuHb8bVOsdvPT2Kv02KQHPLzIrkC8bEd6A3nKP3PRMfTDo5R3idtThQTbhYDd7 X-Received: by 2002:a17:902:e84e:b0:1b8:6cae:3570 with SMTP id t14-20020a170902e84e00b001b86cae3570mr14784284plg.11.1694510149380; Tue, 12 Sep 2023 02:15:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694510149; cv=none; d=google.com; s=arc-20160816; b=LKzlQs5Be9vWfnupBN9ZCncZRdOx3QfuCz1J0oUR0P+JuQ1/zoAmturRr99eMKgc4L yBnyWg+l+tb/OV2gR5ZqoEYgSGhPvSlehnW0SC5jeENo6wVDR5PwE5pkl6CTQodV5XzS TALJUbUxItURd62oxDoHGEnMAw5hu45yPiTmBr6txH6nUrOpcJWlyipaO7Y4+XIOYXNx GR8Lcd3yiKPoLlZ368XeCOgDvNG9WehSrTs2D7y6bdoYDzLLYpfPFO3/WW5PC0ZNHrFt ndy8aZx7eViVPzKQ1dKBChAG8AmrcEQ/KyoBiJ3LrYD6QUsibD7ZRo+25YY8M+RhqA33 IbEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:dkim-signature; bh=xEW+R9vLIfOy8Qs86KH5LMpYh7OoDGKz314Er6GdaNc=; fh=WGxnbchXB1nh8WtfYTQqAYq5ggcl91wEfddYAfjE7VI=; b=u6fLnizRhoA7UIQd00N69kUNQyeb0Ytq6KSZuDtP5P4BfepVORzqbCg4VCpUg5oSoV o1C1u+T1QyqBhGuC+ER4LcTDpundP9GE4mHzlil5ZPrC7+UPKLkrrKI8BaT8F0nQhROH GhoMbUwgaQpmDGKzPPKCPLEWNg6MuthKg3yQ/sosToRnxk1XQdMaoeR3eoH0MwOteP47 GkI5/mCtpWlL2EnOYZFQjZppQptUD3heDZBb6B7LqQssWHOwigw1UG7YlQ8eEHgNwE/T An2QUlLIQESIqQn42t5jDQQhW278VOWGs6QhYnIupgHIzVOFDuCogbs+MLDAKO8jFHzK vYlA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=sAYRQ+in; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from agentk.vger.email (agentk.vger.email. [2620:137:e000::3:2]) by mx.google.com with ESMTPS id a13-20020a170902eccd00b001b662f49f60si5871272plh.419.2023.09.12.02.15.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Sep 2023 02:15:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) client-ip=2620:137:e000::3:2; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=sAYRQ+in; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:2 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 79CEF8144188; Tue, 12 Sep 2023 02:03:40 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233487AbjILJDM (ORCPT + 99 others); Tue, 12 Sep 2023 05:03:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50556 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233378AbjILJCG (ORCPT ); Tue, 12 Sep 2023 05:02:06 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 06560173D for ; Tue, 12 Sep 2023 02:02:03 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-d71f505d21dso5161853276.3 for ; Tue, 12 Sep 2023 02:02:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1694509322; x=1695114122; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=xEW+R9vLIfOy8Qs86KH5LMpYh7OoDGKz314Er6GdaNc=; b=sAYRQ+incHFE494QSEPMH8FE4aAtacx9nm9CRmCx5NMYFgsn9fl720RukJvbtbfuWE dBnnZo9hSK5DX/X6zUy8E16jsKLILDCDIhSw+c9nOYyQ+hk44FyUXuWnx0XqJzHQuwNQ ApiPwkOks3YUTLaxYs0bLpvicf9eVGRRKOJJgtgome3urxb+ltIanOBz3UHxonrZrNIj ZAY6JH//VReylvFlFXzIuYmJ7ga/1fBjisc2N8WHSRzi7BC6VV24LXV5OVdZkH1v7192 CN6xvxy6x0/6IUBVp66UyLY23SOQzki1Epzx+2rUDFic0T/3/3bSW/pBp7iNlqy8uO/R +9Ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694509322; x=1695114122; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=xEW+R9vLIfOy8Qs86KH5LMpYh7OoDGKz314Er6GdaNc=; b=uU/p/4E3OQuvajtTgrs3+L1WvyiQMcDXqhnFtH6uIW3vyUWTtWXPwNzN/0xtD1Xrl8 XgM9N6Gbn48EBFISUc5GhWZ/VTPYNDKRl0YX2+WvixWQ4SMd4HMlVCRB75LVCg7zy0bg h4kFfSmb716M6qN2/5J366exOGt5epeCqwZ6V7BwL1zkHtWTuxw8Xjazb4c7w+vfZRLE ocuJJY9aVETOvk6JrSQE7I+7ar6aoUOrp0ha00AuJCcVr3bPR7g8feN4v5cbawZ2uGNy 17RLCE7pN5zJk2R2w+CxNDGQV1WAy/G93uMiTw6kpLqF2dYWa0hMeG0Yvj9yNGwxyWYg JRvg== X-Gm-Message-State: AOJu0YxfmUSGFBOs6skpiRkuYd+t3ACvqd8KjRLrPM7SDMZGdISQT74A Xo0V7xPjlnBVN2LY+WJzkFH9forO X-Received: from palermo.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:118a]) (user=ardb job=sendgmr) by 2002:a25:ea41:0:b0:d05:98ef:c16b with SMTP id o1-20020a25ea41000000b00d0598efc16bmr240888ybe.5.1694509322283; Tue, 12 Sep 2023 02:02:02 -0700 (PDT) Date: Tue, 12 Sep 2023 09:01:06 +0000 In-Reply-To: <20230912090051.4014114-17-ardb@google.com> Mime-Version: 1.0 References: <20230912090051.4014114-17-ardb@google.com> X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Developer-Signature: v=1; a=openpgp-sha256; l=10096; i=ardb@kernel.org; h=from:subject; bh=eEUB5kAXRmeNSiFEyi73U861U2SHinpGxVQGzWYqgYY=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIZVB4xrzQ4cKo/CIZX3fOH5UpeXNfTm99ew7i2mM/3Ysa iiLmqPdUcrCIMbBICumyCIw+++7nacnStU6z5KFmcPKBDKEgYtTACZSUM3I8G7tlw9NTlW9zV5l iTvufz1plhtz9NCz9OyERZxTH4U2H2X4w3fw+P86k0eHNV82sfx8MX/RV46omti1ZcfEWZ4Y551 k5QMA X-Mailer: git-send-email 2.42.0.283.g2d96d420d3-goog Message-ID: <20230912090051.4014114-32-ardb@google.com> Subject: [PATCH v2 15/15] x86/boot: Increase section and file alignment to 4k/512 From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , Evgeniy Baskov , Borislav Petkov , Dave Hansen , Ingo Molnar , Thomas Gleixner , Peter Jones , Matthew Garrett , Gerd Hoffmann , Kees Cook , "H. Peter Anvin" Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Tue, 12 Sep 2023 02:03:40 -0700 (PDT) X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email From: Ard Biesheuvel Align x86 with other EFI architectures, and increase the section alignment to the EFI page size (4k), so that firmware is able to honour the section permission attributes and map code read-only and data non-executable. There are a number of requirements that have to be taken into account: - the sign tools get cranky when there are gaps between sections in the file view of the image - the virtual offset of each section must be aligned to the image's section alignment - the file offset *and size* of each section must be aligned to the image's file alignment - the image size must be aligned to the section alignment - each section's virtual offset must be greater than or equal to the size of the headers. In order to meet all these requirements, while avoiding the need for lots of padding to accommodate the .compat section, the latter is placed at an arbitrary offset towards the end of the image, but aligned to the minimum file alignment (512 bytes). The space before the .text section is therefore distributed between the PE header, the .setup section and the .compat section, leaving no gaps in the file coverage, making the signing tools happy. Signed-off-by: Ard Biesheuvel --- arch/x86/boot/compressed/vmlinux.lds.S | 4 +- arch/x86/boot/header.S | 75 +++++++++------- arch/x86/boot/setup.ld | 7 +- arch/x86/boot/tools/build.c | 90 +------------------- 4 files changed, 51 insertions(+), 125 deletions(-) diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index 5326f3b44194..3df57cdf5003 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S @@ -43,13 +43,13 @@ SECTIONS *(.rodata.*) _erodata = . ; } - .data : { + .data : ALIGN(0x1000) { _data = . ; *(.data) *(.data.*) /* add 4 bytes of extra space for a CRC-32 checksum */ - . = ALIGN(. + 4, 0x20); + . = ALIGN(. + 4, 0x200); _edata = . ; } . = ALIGN(L1_CACHE_BYTES); diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index a1f986105f00..597b1ef745db 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -36,6 +36,9 @@ SYSSEG = 0x1000 /* historical load address >> 4 */ #define ROOT_RDONLY 1 #endif + .set salign, 0x1000 + .set falign, 0x200 + .code16 .section ".bstext", "ax" #ifdef CONFIG_EFI_STUB @@ -82,7 +85,7 @@ optional_header: .long setup_size + ZO_efi_pe_entry # AddressOfEntryPoint - .long 0x0200 # BaseOfCode + .long setup_size # BaseOfCode #ifdef CONFIG_X86_32 .long 0 # data #endif @@ -93,8 +96,8 @@ extra_header_fields: #else .quad 0 # ImageBase #endif - .long 0x20 # SectionAlignment - .long 0x20 # FileAlignment + .long salign # SectionAlignment + .long falign # FileAlignment .word 0 # MajorOperatingSystemVersion .word 0 # MinorOperatingSystemVersion .word LINUX_EFISTUB_MAJOR_VERSION # MajorImageVersion @@ -103,9 +106,10 @@ extra_header_fields: .word 0 # MinorSubsystemVersion .long 0 # Win32VersionValue - .long setup_size + ZO__end # SizeOfImage + .long setup_size + ZO__end + pecompat_vsize + # SizeOfImage - .long 0x200 # SizeOfHeaders + .long salign # SizeOfHeaders .long 0 # CheckSum .word IMAGE_SUBSYSTEM_EFI_APPLICATION # Subsystem (EFI application) #ifdef CONFIG_EFI_DXE_MEM_ATTRIBUTES @@ -136,44 +140,51 @@ extra_header_fields: # Section table section_table: - # - # The offset & size fields are filled in by build.c. - # .ascii ".setup" .byte 0 .byte 0 - .long 0 - .long 0x0 # startup_{32,64} - .long 0 # Size of initialized data - # on disk - .long 0x0 # startup_{32,64} - .long 0 # PointerToRelocations - .long 0 # PointerToLineNumbers - .word 0 # NumberOfRelocations - .word 0 # NumberOfLineNumbers - .long IMAGE_SCN_CNT_CODE | \ + .long setup_size - salign # VirtualSize + .long salign # VirtualAddress + .long pecompat_fstart - salign # SizeOfRawData + .long salign # PointerToRawData + + .long 0, 0, 0 + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ IMAGE_SCN_MEM_READ | \ - IMAGE_SCN_MEM_EXECUTE # Characteristics + IMAGE_SCN_MEM_DISCARDABLE # Characteristics #ifdef CONFIG_EFI_MIXED - # - # The offset & size fields are filled in by build.c. - # .asciz ".compat" - .long 0 - .long 0x0 - .long 0 # Size of initialized data - # on disk - .long 0x0 - .long 0 # PointerToRelocations - .long 0 # PointerToLineNumbers - .word 0 # NumberOfRelocations - .word 0 # NumberOfLineNumbers + + .long 8 # VirtualSize + .long setup_size + ZO__end # VirtualAddress + .long pecompat_fsize # SizeOfRawData + .long pecompat_fstart # PointerToRawData + + .long 0, 0, 0 .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ IMAGE_SCN_MEM_READ | \ IMAGE_SCN_MEM_DISCARDABLE # Characteristics -#endif + /* + * Put the IA-32 machine type and the associated entry point address in + * the .compat section, so loaders can figure out which other execution + * modes this image supports. + */ + .pushsection ".pecompat", "a", @progbits + .balign falign + .set pecompat_vsize, salign + .globl pecompat_fstart +pecompat_fstart: + .byte 0x1 # version + .byte 8 # size + .word IMAGE_FILE_MACHINE_I386 # PE machine type + .long setup_size + ZO_efi32_pe_entry # entrypoint + .popsection +#else + .set pecompat_vsize, 0 + .set pecompat_fstart, setup_size +#endif .ascii ".text" .byte 0 .byte 0 diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld index 9b551eacffa8..02e2c0b8c094 100644 --- a/arch/x86/boot/setup.ld +++ b/arch/x86/boot/setup.ld @@ -36,16 +36,17 @@ SECTIONS . = ALIGN(16); .data : { *(.data*) } + .pecompat : { *(.pecompat) } + PROVIDE(pecompat_fsize = setup_size - pecompat_fstart); + .signature : { setup_sig = .; LONG(0x5a5aaa55) - /* reserve some extra space for the compat section */ - setup_size = ABSOLUTE(ALIGN(. + 32, 512)); + setup_size = ABSOLUTE(ALIGN(4096)); setup_sects = ABSOLUTE(setup_size / 512); } - . = ALIGN(16); .bss : { diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index faccff9743a3..10311d77c67f 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -47,9 +47,6 @@ typedef unsigned int u32; /* This must be large enough to hold the entire setup */ u8 buf[SETUP_SECT_MAX*512]; -#define PECOFF_COMPAT_RESERVE 0x20 - -static unsigned long efi32_pe_entry; static unsigned long _edata; /*----------------------------------------------------------------------*/ @@ -136,85 +133,6 @@ static void usage(void) die("Usage: build setup system zoffset.h image"); } -#ifdef CONFIG_EFI_STUB - -static void update_pecoff_section_header_fields(char *section_name, u32 vma, u32 size, u32 datasz, u32 offset) -{ - unsigned int pe_header; - unsigned short num_sections; - u8 *section; - - pe_header = get_unaligned_le32(&buf[0x3c]); - num_sections = get_unaligned_le16(&buf[pe_header + 6]); - -#ifdef CONFIG_X86_32 - section = &buf[pe_header + 0xa8]; -#else - section = &buf[pe_header + 0xb8]; -#endif - - while (num_sections > 0) { - if (strncmp((char*)section, section_name, 8) == 0) { - /* section header size field */ - put_unaligned_le32(size, section + 0x8); - - /* section header vma field */ - put_unaligned_le32(vma, section + 0xc); - - /* section header 'size of initialised data' field */ - put_unaligned_le32(datasz, section + 0x10); - - /* section header 'file offset' field */ - put_unaligned_le32(offset, section + 0x14); - - break; - } - section += 0x28; - num_sections--; - } -} - -static void update_pecoff_section_header(char *section_name, u32 offset, u32 size) -{ - update_pecoff_section_header_fields(section_name, offset, size, size, offset); -} - -static void update_pecoff_setup(unsigned int size) -{ - u32 setup_offset = 0x200; - u32 compat_offset = size - PECOFF_COMPAT_RESERVE; - u32 setup_size = compat_offset - setup_offset; - - update_pecoff_section_header(".setup", setup_offset, setup_size); - -#ifdef CONFIG_EFI_MIXED - update_pecoff_section_header(".compat", compat_offset, PECOFF_COMPAT_RESERVE); - - /* - * Put the IA-32 machine type (0x14c) and the associated entry point - * address in the .compat section, so loaders can figure out which other - * execution modes this image supports. - */ - buf[compat_offset] = 0x1; - buf[compat_offset + 1] = 0x8; - put_unaligned_le16(0x14c, &buf[compat_offset + 2]); - put_unaligned_le32(efi32_pe_entry + size, &buf[compat_offset + 4]); -#endif -} - -#else - -static inline void update_pecoff_setup(unsigned int size) {} - -#endif /* CONFIG_EFI_STUB */ - -static int reserve_pecoff_compat_section(int c) -{ - /* Reserve 0x20 bytes for .compat section */ - memset(buf+c, 0, PECOFF_COMPAT_RESERVE); - return PECOFF_COMPAT_RESERVE; -} - /* * Parse zoffset.h and find the entry points. We could just #include zoffset.h * but that would mean tools/build would have to be rebuilt every time. It's @@ -243,7 +161,6 @@ static void parse_zoffset(char *fname) p = (char *)buf; while (p && *p) { - PARSE_ZOFS(p, efi32_pe_entry); PARSE_ZOFS(p, _edata); p = strchr(p, '\n'); @@ -283,17 +200,14 @@ int main(int argc, char ** argv) die("Boot block hasn't got boot flag (0xAA55)"); fclose(file); - c += reserve_pecoff_compat_section(c); - /* Pad unused space with zeros */ - setup_sectors = (c + 511) / 512; + setup_sectors = (c + 4095) / 4096; + setup_sectors *= 8; if (setup_sectors < SETUP_SECT_MIN) setup_sectors = SETUP_SECT_MIN; i = setup_sectors*512; memset(buf+c, 0, i-c); - update_pecoff_setup(i); - /* Open and stat the kernel file */ fd = open(argv[2], O_RDONLY); if (fd < 0) -- 2.42.0.283.g2d96d420d3-goog