From patchwork Tue Apr 18 13:49:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 674836 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 5F8A2C77B75 for ; Tue, 18 Apr 2023 13:50:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231971AbjDRNuJ (ORCPT ); Tue, 18 Apr 2023 09:50:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229756AbjDRNuI (ORCPT ); Tue, 18 Apr 2023 09:50:08 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 310505267 for ; Tue, 18 Apr 2023 06:50:07 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id C10A162822 for ; Tue, 18 Apr 2023 13:50:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B3689C433D2; Tue, 18 Apr 2023 13:50:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1681825806; bh=NN1vX7GS8UcvvMTsQiKYpCnrGd1Eg9mW+O4yymmSSt8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qd3ui+f8dEpD4/5QJfvORJNIux1XawcE0g94nedKnxMrii9QykTiOCZdb9jaXRVuo dqNY1blHi+Fxtl5Wttyq/EAlJr9LR4wrLkmnEbbZWohqp8AtJk7bqiQKlzpZdyYepZ nQHrFOcM922XMqGeBgSAhMHHQZfsoM9UebEJAF/XetBL65VdHL3pUCyhernIuvlsfD 8hhxVIxQItS+Y3SGtLDj1czzABdl/2Ca0SUako3JcSuYuKDKeqVUEEx7QSYDb06707 +q75JJBN5UV/+5j9Qm4XN9Loj9z7/qbZwkmgkdlO/k2tO5v64a6dtXVNgU17ZShP/u 4loZn1tOyLmAQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, broonie@kernel.org, will@kernel.org, catalin.marinas@arm.com, Ard Biesheuvel Subject: [PATCH v2 1/6] efi/pe: Import new BTI/IBT header flags from the spec Date: Tue, 18 Apr 2023 15:49:47 +0200 Message-Id: <20230418134952.1170141-2-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230418134952.1170141-1-ardb@kernel.org> References: <20230418134952.1170141-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1294; i=ardb@kernel.org; h=from:subject; bh=NN1vX7GS8UcvvMTsQiKYpCnrGd1Eg9mW+O4yymmSSt8=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIcVu/s8k7iT33yaTPF47XttwKeGXtKGUAOfpZ/634k4EJ rTES5Z3lLIwiHEwyIopsgjM/vtu5+mJUrXOs2Rh5rAygQxh4OIUgImoPmb4w/FtuaTQ/mtu9Ycb 6+aXRiks+CuYuyzo2lTpJVPWaWuHlTL8FZxbM+Xdy4nV+xQ/rshJaa2+m5D4uojnuufO2WKht/O ucQIA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The latest version of your favorite fork of the PE/COFF spec includes a new type of header flag that is intended to be used in the context of EFI firmware to indicate to the image loader that the executable regions of an image can be mapped with BTI/IBT enforcement enabled. So let's import these definitions so we can use them in subsequent patches. Signed-off-by: Ard Biesheuvel --- include/linux/pe.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/linux/pe.h b/include/linux/pe.h index 6ffabf1e6d039e67..5e1e115408702c77 100644 --- a/include/linux/pe.h +++ b/include/linux/pe.h @@ -118,6 +118,9 @@ #define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000 #define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000 +#define IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001 +#define IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 0x0040 + /* they actually defined 0x00000000 as well, but I think we'll skip that one. */ #define IMAGE_SCN_RESERVED_0 0x00000001 #define IMAGE_SCN_RESERVED_1 0x00000002 @@ -165,6 +168,7 @@ #define IMAGE_SCN_MEM_WRITE 0x80000000 /* writeable */ #define IMAGE_DEBUG_TYPE_CODEVIEW 2 +#define IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20 #ifndef __ASSEMBLY__ From patchwork Tue Apr 18 13:49:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 676730 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 B37F8C6FD18 for ; Tue, 18 Apr 2023 13:50:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229756AbjDRNuN (ORCPT ); Tue, 18 Apr 2023 09:50:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36734 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232278AbjDRNuL (ORCPT ); Tue, 18 Apr 2023 09:50:11 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22BD1468D for ; Tue, 18 Apr 2023 06:50:09 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AF6BE62845 for ; Tue, 18 Apr 2023 13:50:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9F3F3C4339B; Tue, 18 Apr 2023 13:50:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1681825808; bh=vgDh/RZI17YIdpHDLz/KRWWk764g3EIBUUFAxv5YzVY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DjaOReOAdZGeGHfxZlUhOHHsPy/K40b0p957rR7qmufsekHIceGm9DiCdFpaDWn3U GyW6eTF9g96Khb8x/X3T45ZO4ODFF48d8io40wRQW7a1mG/58SFcjCWPokvAQjcP4S vAaPmIGX74jX9ROoVi1LdZkinHN3yPi2UAqMgKTH3ly2VXvosz59rmXzE7gfPB4vYe dOA7G+uryhtdbu4psJ1LtX+ScXIWEv4BTHCl7jYR6LdZDs/TtkqJEbHsBIGDyjDUDc JHipOiJR1kSzc9z9r7kiJv/b2HC3L0j/YsvzegayqXk6DORFU7ohIffFYDixTxLnrb tguR221kfyjSQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, broonie@kernel.org, will@kernel.org, catalin.marinas@arm.com, Ard Biesheuvel Subject: [PATCH v2 2/6] arm64: efi: Enable BTI codegen and add PE/COFF annotation Date: Tue, 18 Apr 2023 15:49:48 +0200 Message-Id: <20230418134952.1170141-3-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230418134952.1170141-1-ardb@kernel.org> References: <20230418134952.1170141-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4886; i=ardb@kernel.org; h=from:subject; bh=vgDh/RZI17YIdpHDLz/KRWWk764g3EIBUUFAxv5YzVY=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIcVu/i+rTjZ2fvm168X+STC+zlI+WBnLU6Yw22vGqSTNZ pE7XEIdpSwMYhwMsmKKLAKz/77beXqiVK3zLFmYOaxMIEMYuDgFYCLxpxn+igc9f/OO023a1yM9 0v/X7DKxZHXpNP33aAF/3cYFk9wrxBkZJrmkcAYpZz9sM/quc4axbUJc/4U1x6tcBNo6Kuf6Fzf wAwA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org UEFI heavily relies on so-called protocols, which are essentially tables populated with pointers to executable code, and these are invoked indirectly using BR or BLR instructions. This makes the EFI execution context vulnerable to attacks on forward edge control flow, and so it would help if we could enable hardware enforcement (BTI) on CPUs that implement it. So let's no longer disable BTI codegen for the EFI stub, and set the newly introduced PE/COFF header flag when the kernel is built with BTI landing pads. Signed-off-by: Ard Biesheuvel Reviewed-by: Mark Brown --- arch/arm64/kernel/efi-header.S | 71 ++++++++++++-------- drivers/firmware/efi/libstub/Makefile | 3 +- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S index d731b4655df8eb27..11d7f7de202d0ed2 100644 --- a/arch/arm64/kernel/efi-header.S +++ b/arch/arm64/kernel/efi-header.S @@ -81,9 +81,47 @@ .quad 0 // CertificationTable .quad 0 // BaseRelocationTable -#ifdef CONFIG_DEBUG_EFI +#if defined(CONFIG_DEBUG_EFI) || defined(CONFIG_ARM64_BTI_KERNEL) .long .Lefi_debug_table - .L_head // DebugTable .long .Lefi_debug_table_size + + /* + * The debug table is referenced via its Relative Virtual Address (RVA), + * which is only defined for those parts of the image that are covered + * by a section declaration. Since this header is not covered by any + * section, the debug table must be emitted elsewhere. So stick it in + * the .init.rodata section instead. + * + * Note that the payloads themselves are permitted to have zero RVAs, + * which means we can simply put those right after the section headers. + */ + __INITRODATA + + .align 2 +.Lefi_debug_table: +#ifdef CONFIG_DEBUG_EFI + // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY + .long 0 // Characteristics + .long 0 // TimeDateStamp + .short 0 // MajorVersion + .short 0 // MinorVersion + .long IMAGE_DEBUG_TYPE_CODEVIEW // Type + .long .Lefi_debug_entry_size // SizeOfData + .long 0 // RVA + .long .Lefi_debug_entry - .L_head // FileOffset +#endif +#ifdef CONFIG_ARM64_BTI_KERNEL + .long 0 // Characteristics + .long 0 // TimeDateStamp + .short 0 // MajorVersion + .short 0 // MinorVersion + .long IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS // Type + .long 4 // SizeOfData + .long 0 // RVA + .long .Lefi_dll_characteristics_ex - .L_head // FileOffset +#endif + .set .Lefi_debug_table_size, . - .Lefi_debug_table + .previous #endif // Section table @@ -119,33 +157,6 @@ .set .Lsection_count, (. - .Lsection_table) / 40 #ifdef CONFIG_DEBUG_EFI - /* - * The debug table is referenced via its Relative Virtual Address (RVA), - * which is only defined for those parts of the image that are covered - * by a section declaration. Since this header is not covered by any - * section, the debug table must be emitted elsewhere. So stick it in - * the .init.rodata section instead. - * - * Note that the EFI debug entry itself may legally have a zero RVA, - * which means we can simply put it right after the section headers. - */ - __INITRODATA - - .align 2 -.Lefi_debug_table: - // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY - .long 0 // Characteristics - .long 0 // TimeDateStamp - .short 0 // MajorVersion - .short 0 // MinorVersion - .long IMAGE_DEBUG_TYPE_CODEVIEW // Type - .long .Lefi_debug_entry_size // SizeOfData - .long 0 // RVA - .long .Lefi_debug_entry - .L_head // FileOffset - - .set .Lefi_debug_table_size, . - .Lefi_debug_table - .previous - .Lefi_debug_entry: // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY .ascii "NB10" // Signature @@ -157,6 +168,10 @@ .set .Lefi_debug_entry_size, . - .Lefi_debug_entry #endif +#ifdef CONFIG_ARM64_BTI_KERNEL +.Lefi_dll_characteristics_ex: + .long IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT +#endif .balign SEGMENT_ALIGN .Lefi_header_end: diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 80d85a5169fb2c72..3abb2b357482a416 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -23,8 +23,7 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ # arm64 uses the full KBUILD_CFLAGS so it's necessary to explicitly # disable the stackleak plugin cflags-$(CONFIG_ARM64) += -fpie $(DISABLE_STACKLEAK_PLUGIN) \ - -fno-unwind-tables -fno-asynchronous-unwind-tables \ - $(call cc-option,-mbranch-protection=none) + -fno-unwind-tables -fno-asynchronous-unwind-tables cflags-$(CONFIG_ARM) += -DEFI_HAVE_STRLEN -DEFI_HAVE_STRNLEN \ -DEFI_HAVE_MEMCHR -DEFI_HAVE_STRRCHR \ -DEFI_HAVE_STRCMP -fno-builtin -fpic \ From patchwork Tue Apr 18 13:49:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 674835 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 AA04DC77B76 for ; Tue, 18 Apr 2023 13:50:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231577AbjDRNuO (ORCPT ); Tue, 18 Apr 2023 09:50:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36754 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232441AbjDRNuM (ORCPT ); Tue, 18 Apr 2023 09:50:12 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1EFF19031 for ; Tue, 18 Apr 2023 06:50:11 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 99C0462828 for ; Tue, 18 Apr 2023 13:50:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 89D7DC433A0; Tue, 18 Apr 2023 13:50:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1681825810; bh=itkz19a6AQffFf+lI3+0O4zeHpmhbSPDYT1Qi9LQ+Uc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GNzToNHcnx5kSIlCsDHfu54FmEEnLhiYCsUfjDBzG7wTJAfoQjEkJYnskmy2mC+45 qYiS+uAVieJXOXZieIG0GUmzejsS7OsuCVE8CR2C+9VwcoaZkmrn4AQuuWqRMUY5gm BCwiejlkIHkyzVfikjQ3+fqUYM4ruEILCNTLX7kOGjStsQFtsXegB5/IG1xbjLYhXP 1HSqDG7kV4mc5k8OrpOhyDgd64UveULYyqdrOFy2cnq/LE6tOO1px3KBoFy2WUpSLR Coz4SU2xdQmBjs6rp6WmxDtG80w8ETmH6F1NJWiUOeNqNJWQtDsn1xJJvGaKRagk4b BybqoKMl/2ymg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, broonie@kernel.org, will@kernel.org, catalin.marinas@arm.com, Ard Biesheuvel Subject: [PATCH v2 3/6] efi/zboot: arm64: Poke kernel code size into the zboot payload image header Date: Tue, 18 Apr 2023 15:49:49 +0200 Message-Id: <20230418134952.1170141-4-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230418134952.1170141-1-ardb@kernel.org> References: <20230418134952.1170141-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2662; i=ardb@kernel.org; h=from:subject; bh=itkz19a6AQffFf+lI3+0O4zeHpmhbSPDYT1Qi9LQ+Uc=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIcVu/p/KqvcB5RqrlPuCz+atn79g9bTJ0+dPqvc8vSCHV WT6jJhrHaUsDGIcDLJiiiwCs/++23l6olSt8yxZmDmsTCBDGLg4BWAiNQKMDDtPcv0QM98ww2fR GutbX46Y/pt9amr6+3/8TnoSxtt2cxczMpx7Hj0v9EC+hfm/M5U92v7+5nK/ou9VW6/I5phxc/m KQ7wA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The EFI zboot code is not built as part of the kernel proper, like the ordinary EFI stub, but still needs access to symbols that are defined only internally in the kernel, and are left unexposed deliberately to avoid creating ABI inadvertently that we're stuck with later. So instead of passing the ordinary Image file to the zboot make rules, create an alternate version Image.zboot that has the code size copied into the header into a field that has meaning in the bare metal boot ABI, but is actually not used anymore, and is always set to 0x0. Signed-off-by: Ard Biesheuvel --- arch/arm64/boot/Makefile | 23 +++++++++++++++++++- arch/arm64/kernel/image-vars.h | 4 ++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index c65aee0884103c6f..5d73229604b11061 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile @@ -39,8 +39,29 @@ $(obj)/Image.lzo: $(obj)/Image FORCE $(obj)/Image.zst: $(obj)/Image FORCE $(call if_changed,zstd) -EFI_ZBOOT_PAYLOAD := Image +EFI_ZBOOT_PAYLOAD := Image.zboot EFI_ZBOOT_BFD_TARGET := elf64-littleaarch64 EFI_ZBOOT_MACH_TYPE := ARM64 +# +# The EFI zboot logic needs to know the size of the executable region in the +# image, so let's poke that into the text_offset field of the image header of +# the zboot payload, as that field is no longer used and can thus be repurposed +# for other, purely internal uses. +# +quiet_cmd_copy_and_poke = $(quiet_cmd_objcopy) + cmd_copy_and_poke = $(cmd_objcopy) && /bin/echo -ne "$(POKE_DATA)" | dd bs=1 \ + status=none conv=notrunc seek=$(POKE_OFFSET) of=$@ + +# grab the code size and convert it into something we can echo +$(obj)/$(EFI_ZBOOT_PAYLOAD): POKE_DATA = $(shell $(NM) $<|grep _kernel_codesize|\ + sed -E 's/0+(..)(..)(..)(..) .+/\\x\4\\x\3\\x\2\\x\1/') +$(obj)/$(EFI_ZBOOT_PAYLOAD): POKE_OFFSET := 8 +$(obj)/$(EFI_ZBOOT_PAYLOAD): vmlinux FORCE + $(call if_changed,copy_and_poke) + +OBJCOPYFLAGS_$(EFI_ZBOOT_PAYLOAD) := $(OBJCOPYFLAGS_Image) + +targets += $(EFI_ZBOOT_PAYLOAD) + include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index 8309197c0ebd4a8e..35f3c79595137354 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -108,4 +108,8 @@ KVM_NVHE_ALIAS(kvm_protected_mode_initialized); #endif /* CONFIG_KVM */ +#ifdef CONFIG_EFI_ZBOOT +_kernel_codesize = ABSOLUTE(__inittext_end - _text); +#endif + #endif /* __ARM64_KERNEL_IMAGE_VARS_H */ From patchwork Tue Apr 18 13:49:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 676729 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 6C42AC77B7D for ; Tue, 18 Apr 2023 13:50:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232173AbjDRNuO (ORCPT ); Tue, 18 Apr 2023 09:50:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229978AbjDRNuO (ORCPT ); Tue, 18 Apr 2023 09:50:14 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EE19B468D for ; Tue, 18 Apr 2023 06:50:12 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 84B3E628B6 for ; Tue, 18 Apr 2023 13:50:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 73D45C433A4; Tue, 18 Apr 2023 13:50:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1681825811; bh=Zod0gLV50Ql+WmIuLOmGh7UoZX0DfCWPHhuwknk4N1E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P20uT7A+ztYQyvHg4o1M1pDh3u/tUuynMs6Q6l4AGiQPhnzc+EG8JtVthzRh5OGkN deqnHu0rm8JIs17oUv/Q7PblEhLX7VWSUmO8Vw5wHw2hayYdAT+rC3+EAwk/SNkX8B VznrjSVtUNfMKo+wtG36K/MLsownNc5bAtTPMHB/KBzpVdTTlDTwJvdZJZeeMEvotk EKTV5CURRiMJ1/LIoOx6rBQflw636DZz39DWl34lF01tSpGei4dyrlnt8JVTZWFaoP bOVnV0oZKSVATnEfzam5IIgEIxARwSsXcSKLkyU8HOgCPn0UKuDIGMapaSFoYCDnyh 2alBMdniBRucA== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, broonie@kernel.org, will@kernel.org, catalin.marinas@arm.com, Ard Biesheuvel Subject: [PATCH v2 4/6] efi/zboot: Add BSS padding before compression Date: Tue, 18 Apr 2023 15:49:50 +0200 Message-Id: <20230418134952.1170141-5-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230418134952.1170141-1-ardb@kernel.org> References: <20230418134952.1170141-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5838; i=ardb@kernel.org; h=from:subject; bh=Zod0gLV50Ql+WmIuLOmGh7UoZX0DfCWPHhuwknk4N1E=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIcVu/l/GG6+Ni7mC3zC2xIS+4C09KHZaP+zZwq7H6cu/z 7ybULilo5SFQYyDQVZMkUVg9t93O09PlKp1niULM4eVCWQIAxenAExk0iSGfxb/rdVrNG84e/kk 3nvpf96RPT8h+PJeC3W3N7FbW7wPX2b47/9X5daDtzuqkn761aTEV0eu+75u9dKH9Rq/3vAc0G3 05gEA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org We don't really care about the size of the decompressed image - what matters is how much space needs to be allocated for the image to execute, and this includes space for BSS that is not part of the loadable image and so it is not accounted for in the decompressed size. So let's add some zero padding to the end of the image: this compresses well, and it ensures that BSS is accounted for, and as a bonus, it will be zeroed before launching the image. Since all architectures that implement support for EFI zboot carry this value in the header in the same location, we can just grab it from the binary that is being compressed. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/Makefile.zboot | 36 +++++++++++++++----- drivers/firmware/efi/libstub/zboot-header.S | 2 +- drivers/firmware/efi/libstub/zboot.c | 6 ++-- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/drivers/firmware/efi/libstub/Makefile.zboot b/drivers/firmware/efi/libstub/Makefile.zboot index ccdd6a130d98618e..2d78770236049b21 100644 --- a/drivers/firmware/efi/libstub/Makefile.zboot +++ b/drivers/firmware/efi/libstub/Makefile.zboot @@ -3,6 +3,14 @@ # to be include'd by arch/$(ARCH)/boot/Makefile after setting # EFI_ZBOOT_PAYLOAD, EFI_ZBOOT_BFD_TARGET and EFI_ZBOOT_MACH_TYPE +quiet_cmd_copy_and_pad = PAD $@ + cmd_copy_and_pad = cp $< $@ && \ + truncate -s $(shell hexdump -s16 -n4 -e '"%u"' $<) $@ + +# Pad the file to the size of the uncompressed image in memory, including BSS +$(obj)/vmlinux.bin: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE + $(call if_changed,copy_and_pad) + comp-type-$(CONFIG_KERNEL_GZIP) := gzip comp-type-$(CONFIG_KERNEL_LZ4) := lz4 comp-type-$(CONFIG_KERNEL_LZMA) := lzma @@ -10,16 +18,25 @@ comp-type-$(CONFIG_KERNEL_LZO) := lzo comp-type-$(CONFIG_KERNEL_XZ) := xzkern comp-type-$(CONFIG_KERNEL_ZSTD) := zstd22 -# Copy the SizeOfHeaders, SizeOfCode and SizeOfImage fields from the payload to -# the end of the compressed image. Note that this presupposes a PE header -# offset of 64 bytes, which is what arm64, RISC-V and LoongArch use. -quiet_cmd_compwithsize = $(quiet_cmd_$(comp-type-y)) - cmd_compwithsize = $(cmd_$(comp-type-y)) && ( \ +# in GZIP, the appended le32 carrying the uncompressed size is part of the +# format, but in other cases, we just append it at the end for convenience, +# causing the original tools to complain when checking image integrity. +# So disregard it when calculating the payload size in the zimage header. +zboot-method-y := $(comp-type-y)_with_size +zboot-size-len-y := 12 + +zboot-method-$(CONFIG_KERNEL_GZIP) := gzip +zboot-size-len-$(CONFIG_KERNEL_GZIP) := 8 + +# Copy the SizeOfHeaders and SizeOfCode fields from the payload to the end of +# the compressed image. Note that this presupposes a PE header offset of 64 +# bytes, which is what arm64, RISC-V and LoongArch use. +quiet_cmd_compwithsize = $(quiet_cmd_$(zboot-method-y)) + cmd_compwithsize = $(cmd_$(zboot-method-y)) && ( \ dd status=none if=$< bs=4 count=1 skip=37 ; \ - dd status=none if=$< bs=4 count=1 skip=23 ; \ - dd status=none if=$< bs=4 count=1 skip=36 ) >> $@ + dd status=none if=$< bs=4 count=1 skip=23 ) >> $@ -$(obj)/vmlinuz: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE +$(obj)/vmlinuz: $(obj)/vmlinux.bin FORCE $(call if_changed,compwithsize) OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \ @@ -29,6 +46,7 @@ $(obj)/vmlinuz.o: $(obj)/vmlinuz FORCE AFLAGS_zboot-header.o += -DMACHINE_TYPE=IMAGE_FILE_MACHINE_$(EFI_ZBOOT_MACH_TYPE) \ -DZBOOT_EFI_PATH="\"$(realpath $(obj)/vmlinuz.efi.elf)\"" \ + -DZBOOT_SIZE_LEN=$(zboot-size-len-y) \ -DCOMP_TYPE="\"$(comp-type-y)\"" $(obj)/zboot-header.o: $(srctree)/drivers/firmware/efi/libstub/zboot-header.S FORCE @@ -44,4 +62,4 @@ OBJCOPYFLAGS_vmlinuz.efi := -O binary $(obj)/vmlinuz.efi: $(obj)/vmlinuz.efi.elf FORCE $(call if_changed,objcopy) -targets += zboot-header.o vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi +targets += zboot-header.o vmlinux.bin vmlinuz vmlinuz.o vmlinuz.efi.elf vmlinuz.efi diff --git a/drivers/firmware/efi/libstub/zboot-header.S b/drivers/firmware/efi/libstub/zboot-header.S index 445cb646eaaaf1c6..053aba073594936b 100644 --- a/drivers/firmware/efi/libstub/zboot-header.S +++ b/drivers/firmware/efi/libstub/zboot-header.S @@ -17,7 +17,7 @@ __efistub_efi_zboot_header: .long MZ_MAGIC .ascii "zimg" // image type .long __efistub__gzdata_start - .Ldoshdr // payload offset - .long __efistub__gzdata_size - 12 // payload size + .long __efistub__gzdata_size - ZBOOT_SIZE_LEN // payload size .long 0, 0 // reserved .asciz COMP_TYPE // compression type .org .Ldoshdr + 0x38 diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c index 6105e5e2eda4612b..63ece480090032c1 100644 --- a/drivers/firmware/efi/libstub/zboot.c +++ b/drivers/firmware/efi/libstub/zboot.c @@ -91,12 +91,12 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab) efi_info("Decompressing Linux Kernel...\n"); // SizeOfImage from the compressee's PE/COFF header - alloc_size = round_up(get_unaligned_le32(_gzdata_end - 4), + alloc_size = round_up(get_unaligned_le32(_gzdata_end - 12), EFI_ALLOC_ALIGN); // SizeOfHeaders and SizeOfCode from the compressee's PE/COFF header - code_size = get_unaligned_le32(_gzdata_end - 8) + - get_unaligned_le32(_gzdata_end - 12); + code_size = get_unaligned_le32(_gzdata_end - 4) + + get_unaligned_le32(_gzdata_end - 8); // If the architecture has a preferred address for the image, // try that first. From patchwork Tue Apr 18 13:49:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 674834 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 4B7DBC6FD18 for ; Tue, 18 Apr 2023 13:50:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232156AbjDRNuQ (ORCPT ); Tue, 18 Apr 2023 09:50:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36788 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229978AbjDRNuQ (ORCPT ); Tue, 18 Apr 2023 09:50:16 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D38BB5267 for ; Tue, 18 Apr 2023 06:50:14 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6AACB62898 for ; Tue, 18 Apr 2023 13:50:14 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5F2E3C433EF; Tue, 18 Apr 2023 13:50:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1681825813; bh=aBrDCdupW5WFY28jp8yQPFuc9JM8G51UC2UuSAiY7pE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MvBA32gXo/7WTYJSyH1RXIyiUteYju8GcKmVDjNilL45jIAyWwR+MU6yPbbSekR+i bQKE87itTB9UTeDHvxgWgMDnIzqXeW4pALBBA5Jv8OKsP+FuHiGeFxGycbcmVORepW FwcutNWjwyV4TJtgJDAohqfJEhqVn65iNzGle+w2xs98CVap8akVAJg3QPJQnv4ZPL c4Xh5IRwPqoh8aH26ZOXARQL/9zsimc7nDwd5Q3wX1j8dTP1cg3ml2HdWekDun75Fp 7o9/3dI1/4qWGacgmT/kMzMqj1+lQsE9WGeeBmMeXobKjZI5+KfQicSBRgWHV+aOzu 8vOiVlThwiqXQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, broonie@kernel.org, will@kernel.org, catalin.marinas@arm.com, Ard Biesheuvel Subject: [PATCH v2 5/6] efi/zboot: Set forward edge CFI compat header flag if supported Date: Tue, 18 Apr 2023 15:49:51 +0200 Message-Id: <20230418134952.1170141-6-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230418134952.1170141-1-ardb@kernel.org> References: <20230418134952.1170141-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4676; i=ardb@kernel.org; h=from:subject; bh=aBrDCdupW5WFY28jp8yQPFuc9JM8G51UC2UuSAiY7pE=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIcVu/j+xzsOeUy/U7FJME33skPQ51M/1bcn07WJme6b4L mldMnd3RykLgxgHg6yYIovA7L/vdp6eKFXrPEsWZg4rE8gQBi5OAZhIkxEjw5H5Pk8/HI1u/T39 AE9Bzfzuwk2SPZ+ufF6Tviv/72fRrbwMf+Wn9ybL/b7GzMe7d02p6LU9kzdP4d8iP6nPRD7vRKD 9bAYA X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Add some plumbing to the zboot EFI header generation to set the newly introduced DllCharacteristicsEx flag associated with forward edge CFI enforcement instructions (BTI on arm64, IBT on x86) x86 does not currently uses the zboot infrastructure, so let's wire it up only for arm64. Signed-off-by: Ard Biesheuvel --- arch/arm64/boot/Makefile | 1 + drivers/firmware/efi/libstub/Makefile.zboot | 9 +++- drivers/firmware/efi/libstub/zboot-header.S | 49 +++++++++++++------- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index 5d73229604b11061..affbcb0df9db81e5 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile @@ -42,6 +42,7 @@ $(obj)/Image.zst: $(obj)/Image FORCE EFI_ZBOOT_PAYLOAD := Image.zboot EFI_ZBOOT_BFD_TARGET := elf64-littleaarch64 EFI_ZBOOT_MACH_TYPE := ARM64 +EFI_ZBOOT_FORWARD_CFI := $(CONFIG_ARM64_BTI_KERNEL) # # The EFI zboot logic needs to know the size of the executable region in the diff --git a/drivers/firmware/efi/libstub/Makefile.zboot b/drivers/firmware/efi/libstub/Makefile.zboot index 2d78770236049b21..0a9dcc2b13736519 100644 --- a/drivers/firmware/efi/libstub/Makefile.zboot +++ b/drivers/firmware/efi/libstub/Makefile.zboot @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # to be include'd by arch/$(ARCH)/boot/Makefile after setting -# EFI_ZBOOT_PAYLOAD, EFI_ZBOOT_BFD_TARGET and EFI_ZBOOT_MACH_TYPE +# EFI_ZBOOT_PAYLOAD, EFI_ZBOOT_BFD_TARGET, EFI_ZBOOT_MACH_TYPE and +# EFI_ZBOOT_FORWARD_CFI quiet_cmd_copy_and_pad = PAD $@ cmd_copy_and_pad = cp $< $@ && \ @@ -44,10 +45,14 @@ OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \ $(obj)/vmlinuz.o: $(obj)/vmlinuz FORCE $(call if_changed,objcopy) +aflags-zboot-header-$(EFI_ZBOOT_FORWARD_CFI) := \ + -DPE_DLL_CHAR_EX=IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT + AFLAGS_zboot-header.o += -DMACHINE_TYPE=IMAGE_FILE_MACHINE_$(EFI_ZBOOT_MACH_TYPE) \ -DZBOOT_EFI_PATH="\"$(realpath $(obj)/vmlinuz.efi.elf)\"" \ -DZBOOT_SIZE_LEN=$(zboot-size-len-y) \ - -DCOMP_TYPE="\"$(comp-type-y)\"" + -DCOMP_TYPE="\"$(comp-type-y)\"" \ + $(aflags-zboot-header-y) $(obj)/zboot-header.o: $(srctree)/drivers/firmware/efi/libstub/zboot-header.S FORCE $(call if_changed_rule,as_o_S) diff --git a/drivers/firmware/efi/libstub/zboot-header.S b/drivers/firmware/efi/libstub/zboot-header.S index 053aba073594936b..fb676ded47fa4341 100644 --- a/drivers/firmware/efi/libstub/zboot-header.S +++ b/drivers/firmware/efi/libstub/zboot-header.S @@ -78,9 +78,36 @@ __efistub_efi_zboot_header: .quad 0 // ExceptionTable .quad 0 // CertificationTable .quad 0 // BaseRelocationTable -#ifdef CONFIG_DEBUG_EFI +#if defined(PE_DLL_CHAR_EX) || defined(CONFIG_DEBUG_EFI) .long .Lefi_debug_table - .Ldoshdr // DebugTable .long .Lefi_debug_table_size + + .section ".rodata", "a" + .p2align 2 +.Lefi_debug_table: + // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY[] +#ifdef PE_DLL_CHAR_EX + .long 0 // Characteristics + .long 0 // TimeDateStamp + .short 0 // MajorVersion + .short 0 // MinorVersion + .long IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS // Type + .long 4 // SizeOfData + .long 0 // RVA + .long .Lefi_dll_characteristics_ex - .Ldoshdr // FileOffset +#endif +#ifdef CONFIG_DEBUG_EFI + .long 0 // Characteristics + .long 0 // TimeDateStamp + .short 0 // MajorVersion + .short 0 // MinorVersion + .long IMAGE_DEBUG_TYPE_CODEVIEW // Type + .long .Lefi_debug_entry_size // SizeOfData + .long 0 // RVA + .long .Lefi_debug_entry - .Ldoshdr // FileOffset +#endif + .set .Lefi_debug_table_size, . - .Lefi_debug_table + .previous #endif .Lsection_table: @@ -110,23 +137,11 @@ __efistub_efi_zboot_header: .set .Lsection_count, (. - .Lsection_table) / 40 +#ifdef PE_DLL_CHAR_EX +.Lefi_dll_characteristics_ex: + .long PE_DLL_CHAR_EX +#endif #ifdef CONFIG_DEBUG_EFI - .section ".rodata", "a" - .align 2 -.Lefi_debug_table: - // EFI_IMAGE_DEBUG_DIRECTORY_ENTRY - .long 0 // Characteristics - .long 0 // TimeDateStamp - .short 0 // MajorVersion - .short 0 // MinorVersion - .long IMAGE_DEBUG_TYPE_CODEVIEW // Type - .long .Lefi_debug_entry_size // SizeOfData - .long 0 // RVA - .long .Lefi_debug_entry - .Ldoshdr // FileOffset - - .set .Lefi_debug_table_size, . - .Lefi_debug_table - .previous - .Lefi_debug_entry: // EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY .ascii "NB10" // Signature From patchwork Tue Apr 18 13:49:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 676728 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 7F55AC77B76 for ; Tue, 18 Apr 2023 13:50:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229978AbjDRNuT (ORCPT ); Tue, 18 Apr 2023 09:50:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232343AbjDRNuS (ORCPT ); Tue, 18 Apr 2023 09:50:18 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D761A10DE for ; Tue, 18 Apr 2023 06:50:16 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 5607462898 for ; Tue, 18 Apr 2023 13:50:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4950DC4339C; Tue, 18 Apr 2023 13:50:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1681825815; bh=WKSi12TPj0ccbN/qjUB9rtwsQfvcIxbjSFCwov90qm0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Wxy/Pwfp8p5jz5RS51hOfgacYKLpcPDrojAkm92N7X39c9avpdxqILspCbjctHYG5 jSVZSM94thYDke83nHe3XphoZUdzuMkhPxeBiV4q849EfhKmjpnUpva+Tw+3w1hQcJ I+FpVyusd3EuebW5oqsnogbzQz875Ctxf0nxLP8m+RmJgsQRT5SFfa3uQ7BXPf2P/E TCXz50cirIRVVESUIdmp+nPSGSMLcg1Se8IKlANXvPtDWPjqcGV04XQBWD/CXcjFH+ TAFaZG55oKK2SdEMTtLYykGvxPGTvdG58x+zmMgHmIr1CLoezONDf9rT3+e7S+9mr7 RQN7M5x77XujQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, mark.rutland@arm.com, broonie@kernel.org, will@kernel.org, catalin.marinas@arm.com, Ard Biesheuvel Subject: [PATCH v2 6/6] efi/zboot: arm64: Grab code size from image header Date: Tue, 18 Apr 2023 15:49:52 +0200 Message-Id: <20230418134952.1170141-7-ardb@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230418134952.1170141-1-ardb@kernel.org> References: <20230418134952.1170141-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6520; i=ardb@kernel.org; h=from:subject; bh=WKSi12TPj0ccbN/qjUB9rtwsQfvcIxbjSFCwov90qm0=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIcVuAcO7b2F99mHf+0N+T3yx4tS7fbMuGrU6exzInlR/6 N3u738dOkpZGMQ4GGTFFFkEZv99t/P0RKla51myMHNYmUCGMHBxCsBE+qIZ/im0nnwuuYFT8fPz I/9Oefrff5n8SKg67NjEnb+kr9yOf/+RkWHvk58RU1l/azTvfRLezzn54dv/epsnllQKTrzYOsl o9Q82AA== X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Instead of relying on a dodgy dd hack to copy the image code size from the uncompressed image's PE header to the end of the compressed image, let's grab the code size from the text_offset field of the arm64 image header after decompression, which is where the arm64 specific EFI zboot make rules will poke the code size when generating zboot specific version of the binary Image payload. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/Makefile.zboot | 14 +++-------- drivers/firmware/efi/libstub/arm64.c | 26 +++++++++++++++----- drivers/firmware/efi/libstub/efistub.h | 3 +-- drivers/firmware/efi/libstub/zboot.c | 15 +++-------- 4 files changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/firmware/efi/libstub/Makefile.zboot b/drivers/firmware/efi/libstub/Makefile.zboot index 0a9dcc2b13736519..d34d4f0ed33349d5 100644 --- a/drivers/firmware/efi/libstub/Makefile.zboot +++ b/drivers/firmware/efi/libstub/Makefile.zboot @@ -24,21 +24,13 @@ comp-type-$(CONFIG_KERNEL_ZSTD) := zstd22 # causing the original tools to complain when checking image integrity. # So disregard it when calculating the payload size in the zimage header. zboot-method-y := $(comp-type-y)_with_size -zboot-size-len-y := 12 +zboot-size-len-y := 4 zboot-method-$(CONFIG_KERNEL_GZIP) := gzip -zboot-size-len-$(CONFIG_KERNEL_GZIP) := 8 - -# Copy the SizeOfHeaders and SizeOfCode fields from the payload to the end of -# the compressed image. Note that this presupposes a PE header offset of 64 -# bytes, which is what arm64, RISC-V and LoongArch use. -quiet_cmd_compwithsize = $(quiet_cmd_$(zboot-method-y)) - cmd_compwithsize = $(cmd_$(zboot-method-y)) && ( \ - dd status=none if=$< bs=4 count=1 skip=37 ; \ - dd status=none if=$< bs=4 count=1 skip=23 ) >> $@ +zboot-size-len-$(CONFIG_KERNEL_GZIP) := 0 $(obj)/vmlinuz: $(obj)/vmlinux.bin FORCE - $(call if_changed,compwithsize) + $(call if_changed,$(zboot-method-y)) OBJCOPYFLAGS_vmlinuz.o := -I binary -O $(EFI_ZBOOT_BFD_TARGET) \ --rename-section .data=.gzdata,load,alloc,readonly,contents diff --git a/drivers/firmware/efi/libstub/arm64.c b/drivers/firmware/efi/libstub/arm64.c index 8aad8c49d43f18e0..a75933b3b9f41c38 100644 --- a/drivers/firmware/efi/libstub/arm64.c +++ b/drivers/firmware/efi/libstub/arm64.c @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -89,25 +90,38 @@ efi_status_t check_platform_features(void) #endif void efi_cache_sync_image(unsigned long image_base, - unsigned long alloc_size, - unsigned long code_size) + unsigned long alloc_size) { + struct arm64_image_header *header = (void *)image_base; + /* + * In the EFI zboot case, the kernel code size lives in the text_offset + * field of the image header, which is no longer used now that + * TEXT_OFFSET is always 0x0. + */ + unsigned long code_size = le64_to_cpu(header->text_offset); u32 ctr = read_cpuid_effective_cachetype(); u64 lsize = 4 << cpuid_feature_extract_unsigned_field(ctr, CTR_EL0_DminLine_SHIFT); /* only perform the cache maintenance if needed for I/D coherency */ if (!(ctr & BIT(CTR_EL0_IDC_SHIFT))) { + unsigned long base = image_base; + unsigned long size = code_size; + do { - asm("dc " DCTYPE ", %0" :: "r"(image_base)); - image_base += lsize; - code_size -= lsize; - } while (code_size >= lsize); + asm("dc " DCTYPE ", %0" :: "r"(base)); + base += lsize; + size -= lsize; + } while (size >= lsize); } asm("ic ialluis"); dsb(ish); isb(); + + header->text_offset = 0x0; + + efi_remap_image(image_base, alloc_size, code_size); } unsigned long __weak primary_entry_offset(void) diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 148013bcb5f89fdd..67d5a20802e0b7c6 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -1066,8 +1066,7 @@ struct screen_info *__alloc_screen_info(void); void free_screen_info(struct screen_info *si); void efi_cache_sync_image(unsigned long image_base, - unsigned long alloc_size, - unsigned long code_size); + unsigned long alloc_size); struct efi_smbios_record { u8 type; diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c index 63ece480090032c1..e5d7fa1f1d8fd160 100644 --- a/drivers/firmware/efi/libstub/zboot.c +++ b/drivers/firmware/efi/libstub/zboot.c @@ -50,8 +50,7 @@ static unsigned long alloc_preferred_address(unsigned long alloc_size) } void __weak efi_cache_sync_image(unsigned long image_base, - unsigned long alloc_size, - unsigned long code_size) + unsigned long alloc_size) { // Provided by the arch to perform the cache maintenance necessary for // executable code loaded into memory to be safe for execution. @@ -66,7 +65,7 @@ asmlinkage efi_status_t __efiapi efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab) { unsigned long compressed_size = _gzdata_end - _gzdata_start; - unsigned long image_base, alloc_size, code_size; + unsigned long image_base, alloc_size; efi_loaded_image_t *image; efi_status_t status; char *cmdline_ptr; @@ -91,13 +90,9 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab) efi_info("Decompressing Linux Kernel...\n"); // SizeOfImage from the compressee's PE/COFF header - alloc_size = round_up(get_unaligned_le32(_gzdata_end - 12), + alloc_size = round_up(get_unaligned_le32(_gzdata_end - 4), EFI_ALLOC_ALIGN); - // SizeOfHeaders and SizeOfCode from the compressee's PE/COFF header - code_size = get_unaligned_le32(_gzdata_end - 4) + - get_unaligned_le32(_gzdata_end - 8); - // If the architecture has a preferred address for the image, // try that first. image_base = alloc_preferred_address(alloc_size); @@ -140,9 +135,7 @@ efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab) goto free_image; } - efi_cache_sync_image(image_base, alloc_size, code_size); - - efi_remap_image(image_base, alloc_size, code_size); + efi_cache_sync_image(image_base, alloc_size); status = efi_stub_common(handle, image, image_base, cmdline_ptr);