From patchwork Fri Aug 18 13:44:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 715253 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 59123C71155 for ; Fri, 18 Aug 2023 13:46:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1377310AbjHRNp6 (ORCPT ); Fri, 18 Aug 2023 09:45:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1377326AbjHRNpd (ORCPT ); Fri, 18 Aug 2023 09:45:33 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B50B4206; Fri, 18 Aug 2023 06:45:22 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 9DBE461D29; Fri, 18 Aug 2023 13:45:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3E6FAC433CA; Fri, 18 Aug 2023 13:45:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1692366321; bh=SudZY6dM7iSHDEmunRbCEUlfeF/tUhKpZ/EYxjc0s/s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cimQY2u8Md+cTQUQKq3hu/hZRzXj0O6p0yrhV/8Pm0Zdz/d6lG6895KnN5VDtiJLH vl+FnH2uwaHkjq70KugigaTZfboNBBTe+EsXezVPhrdtYCDhv9lYdHDmY8Z4l5f3HK AH3MhsySmoeXYzaEuPEn/qXK2boU9+1HG4c724fWK5HRSpSjTUfUKpXlsoy3xqMBvI i9ZZV1DLk4mfPF4vDUv5/txT41rPx8LACuiBOO/J9ns9eqcKBpdp8JVZf3W6ITKsXk +GLvdTt7EQFOI8gyG/6zazpasv10HbpeIlao/afdMrCVlq2l/s4+7yFQaMVSqSqq8I E8MFhNE3MmaWw== 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" , =?utf-8?q?Marvin_H=C3=A4user?= Subject: [PATCH 12/17] x86/boot: Derive file size from _edata symbol Date: Fri, 18 Aug 2023 15:44:17 +0200 Message-Id: <20230818134422.380032-13-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230818134422.380032-1-ardb@kernel.org> References: <20230818134422.380032-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5014; i=ardb@kernel.org; h=from:subject; bh=SudZY6dM7iSHDEmunRbCEUlfeF/tUhKpZ/EYxjc0s/s=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIeV+6aob+1L9p4UdjnJby7qOWeLKN9V7gXq7Dyb/sbJ2f dr6IXd5RykLgxgHg6yYIovA7L/vdp6eKFXrPEsWZg4rE8gQBi5OAZhIbz/DfxcX75tSH9IvXeBb cPSnvdD25w27fdju7K3SXlw+oXLmjBCG//5370y5IxObq753knMgz/ct9VXsaxacZ9QuUlvBulK inxsA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Tweak the linker script so that the value of _edata represents the decompressor binary's file size rounded up to the appropriate alignment. This removes the need to calculate it in the build tool, and will make it easier to refer to the file size from the header directly in subsequent changes to the PE header layout. While adding _edata to the sed regex that parses the compressed vmlinux's symbol list, tweak the regex a bit for conciseness. Note that the resulting binary is identical (for CONFIG_EFI_STUB=y builds) Signed-off-by: Ard Biesheuvel --- arch/x86/boot/Makefile | 2 +- arch/x86/boot/compressed/vmlinux.lds.S | 3 ++ arch/x86/boot/header.S | 2 +- arch/x86/boot/tools/build.c | 30 +++++--------------- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index be1e8b94c93afa4a..b26e30a2d865f72d 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -90,7 +90,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|efi32_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|efi.._stub_entry\|efi\(32\)\?_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|_edata\|z_.*\)$$/\#define ZO_\2 0x\1/p' quiet_cmd_zoffset = ZOFFSET $@ cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index 4ff6ab1b67d9b336..5326f3b441948c5d 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S @@ -47,6 +47,9 @@ SECTIONS _data = . ; *(.data) *(.data.*) + + /* add 4 bytes of extra space for a CRC-32 checksum */ + . = ALIGN(. + 4, 0x20); _edata = . ; } . = ALIGN(L1_CACHE_BYTES); diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index bef9265173757a5a..f1fdffc9d2ca984b 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S @@ -237,7 +237,7 @@ sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */ hdr: setup_sects: .byte (setup_size / 512) - 1 root_flags: .word ROOT_RDONLY -syssize: .long 0 /* Filled in by build.c */ +syssize: .long ZO__edata / 16 ram_size: .word 0 /* Obsolete */ vid_mode: .word SVGA_MODE root_dev: .word 0 /* Default to major/minor 0/0 */ diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c index 665ce7241542e475..082c38a097713a2d 100644 --- a/arch/x86/boot/tools/build.c +++ b/arch/x86/boot/tools/build.c @@ -55,6 +55,7 @@ u8 buf[(SETUP_SECT_NUM+1)*512]; static unsigned long efi_pe_entry; static unsigned long efi32_pe_entry; +static unsigned long _edata; static unsigned long _end; /*----------------------------------------------------------------------*/ @@ -311,6 +312,7 @@ static void parse_zoffset(char *fname) while (p && *p) { PARSE_ZOFS(p, efi_pe_entry); PARSE_ZOFS(p, efi32_pe_entry); + PARSE_ZOFS(p, _edata); PARSE_ZOFS(p, _end); p = strchr(p, '\n'); @@ -323,7 +325,6 @@ int main(int argc, char ** argv) { unsigned int i, sz, setup_sectors; int c; - u32 sys_size; struct stat sb; FILE *file, *dest; int fd; @@ -372,24 +373,14 @@ int main(int argc, char ** argv) die("Unable to open `%s': %m", argv[2]); if (fstat(fd, &sb)) die("Unable to stat `%s': %m", argv[2]); - sz = sb.st_size; + if (_edata != sb.st_size) + die("Unexpected file size `%s': %u != %u", argv[2], _edata, + sb.st_size); + sz = _edata - 4; kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0); if (kernel == MAP_FAILED) die("Unable to mmap '%s': %m", argv[2]); - /* Number of 16-byte paragraphs, including space for a 4-byte CRC */ - sys_size = (sz + 15 + 4) / 16; -#ifdef CONFIG_EFI_STUB - /* - * COFF requires minimum 32-byte alignment of sections, and - * adding a signature is problematic without that alignment. - */ - sys_size = (sys_size + 1) & ~1; -#endif - - /* Patch the setup code with the appropriate size parameters */ - put_unaligned_le32(sys_size, &buf[0x1f4]); - - update_pecoff_text(setup_sectors * 512, i + (sys_size * 16)); + update_pecoff_text(setup_sectors * 512, i + _edata); crc = partial_crc32(buf, i, crc); @@ -401,13 +392,6 @@ int main(int argc, char ** argv) if (fwrite(kernel, 1, sz, dest) != sz) die("Writing kernel failed"); - /* Add padding leaving 4 bytes for the checksum */ - while (sz++ < (sys_size*16) - 4) { - crc = partial_crc32_one('\0', crc); - if (fwrite("\0", 1, 1, dest) != 1) - die("Writing padding failed"); - } - /* Write the CRC */ put_unaligned_le32(crc, buf); if (fwrite(buf, 1, 4, dest) != 4)