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: 13215739 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 348E8C77B75 for ; Tue, 18 Apr 2023 13:50:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=k75/nok/RL6xLuusBOZqw+Xr0zMmyTkwSaoVpOwZZ+I=; b=i+a5e9Yim+lBup 8I0QYlFOdDs3GM33G96CXXq35jZLnGmGlqvlEZMFAxKCEHN/ZHkWSjXPSfw2JAvTcDnQEbR8SO5d0 mTi1uD1cUI8fv2/Aur2EGxYXWIhyHBP9ll4rzSQVFEmEFEUqUZGFemp9Mx/AXw543V6CuwMeIANRs He4AAGUmSZ+qdduGOyw5FtB5mLeL/Ece8YWlqCe4SOaJXlO4WwY6hLwrDzRQPI+uQh1JNQ/X2Z0E3 EEzZQORkcm8aFWQmGfIv6K5Mb9ePKM1KDYQbn2tKhNsXiymiN49mxi72aVRcZWLcL7lX+9NYxR5td HwC3a1KpAzpEBnSOavtA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1polij-002K5T-1r; Tue, 18 Apr 2023 13:50:09 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1polih-002K4h-0W for linux-arm-kernel@lists.infradead.org; Tue, 18 Apr 2023 13:50:08 +0000 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 C142462828; 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230418_065007_240591_3A717582 X-CRM114-Status: GOOD ( 11.67 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13215742 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 655F4C77B75 for ; Tue, 18 Apr 2023 13:51:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=GCysP6gstcvv/lf2fRr3XhmFTqi1sXD30akRKc/r/Wk=; b=JYMCXyx3o8K/K6 ztKTzz+drZak4E2FkgOVjvTzQl+c4TdpIenXB1hGB26CtDXK5i36IqYeX2X7cnDDJw0/BP5KGVVGI /ONQ991s95HMDE83LlqDZYwby4mPJe0iFvOB99s7Swf+q9/BgZumgDYYyQ0xJhea+aTimiHpTKOZg 9S8MHBQPt3tynCa284gfCx+3Xt6HdcxW2F4Du0xeTFnF41PCgYluXhWVdQmOxDk0Ob+82v6pf0CWz p1iltKH24K3m/8LgqxeRQmkBhWypxgG5aSG84kZDDUkiUhBE2n4P3yIt5zIjOOLsv3sB3yYtfjkOE BLbDSiT9evz9+CVOPhHw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1polip-002K7i-2Q; Tue, 18 Apr 2023 13:50:15 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1polij-002K5E-0I for linux-arm-kernel@lists.infradead.org; Tue, 18 Apr 2023 13:50:10 +0000 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 AEEEF62822; 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230418_065009_207104_D924FD1B X-CRM114-Status: GOOD ( 18.51 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13215741 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 37517C6FD18 for ; Tue, 18 Apr 2023 13:51:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=zgWgHXxcuWX1PusY5IBqwqCONFSzulrfVa1T0aolRx8=; b=MUTYv73FP3OkaA XDU5YoyDmxQ4CZ403106FkGOX/v68xP9nMbIVPhIy7+s/UJ5pXcl4uE35UkPZSzcpS2oYfbUNHsUS RaRLXFoxxNjgjb9WzS/AdOzrvk+E2JswdxtkY/8b8fTFnByp1N0wfR8oRxwjrBTeaDZmkkHIIQRCc YY2d7IZLNdOejpVDbwHXCcD5ZbLz15riBr1klLPDuxQ8UrRQZUoaf1oEie0MYNverPhzk4Q7mknnR nPQnibnDQrn/ImkXKC1CeapFMlZSb/bk3Nh6LGyv/F3vkY31Cs+NAEznn9GoE7i8c+f/iOv08Kk2X nWMNPNP6SOWMhEgYKwhw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1poliq-002K8Q-2w; Tue, 18 Apr 2023 13:50:16 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1polil-002K5t-0E for linux-arm-kernel@lists.infradead.org; Tue, 18 Apr 2023 13:50:12 +0000 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 95DBC62898; 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230418_065011_181491_5B3E3824 X-CRM114-Status: GOOD ( 18.58 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13215743 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 51073C77B75 for ; Tue, 18 Apr 2023 13:51:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=N9ylF132QX8Hrv0ZzszcQS6nCubbcWGP649iRfRve7s=; b=Ig/jeaCaGUv4wC mU+KgjAUe3R8fGcM5Bu+KDNqTWUWwvrjUBYZv+iQ2XEHRIWbKiemFCDIGdkn0v4Tso7Hxs8KNuCWO i3uhHOFo+NATQZBuQhdGGcvCK2ohE2AfRTq5RV8PzEKxOs3tHbr3IhiYj4Nz/iQ6TU6uNuUvIEdHz uBDBYmn3LH05Q26W8xR8r3UkFVS6YH5P1jqWtkLKxJgLSLOjQh5uoTzgNqGOoVm+aQRdv1xtsOPKh qfH6TtksvPJcGEsnXEKgwbEjsZmG6rGZDipbK20JzOOG137W+aG/KMbmn5qgRk58QfeRwBkCl+Ikw W26bq4UtseZLDoaDGiig==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1polj0-002KB5-1R; Tue, 18 Apr 2023 13:50:26 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1polim-002K6k-2v for linux-arm-kernel@lists.infradead.org; Tue, 18 Apr 2023 13:50:14 +0000 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 84C3A62934; 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230418_065013_021930_DA76C757 X-CRM114-Status: GOOD ( 20.38 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13215745 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C432EC77B76 for ; Tue, 18 Apr 2023 13:51:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=R7CN40cqmvON7qd13FCOK70ojkPWTj3wKS4EzlfGLUI=; b=zINK4TEvRZCKu7 ipPfg2dakyPgObdqX0JGKNID7i3WEgtzDOJG/6mmF3JIbwz9O4lHX6gd1o56LwG9+PzOme1ZUrs2k 0CJskBKITgGI37GR/z9OLLdbLjy4btRVkhYnjZR4apqDUsmtAW93YjbLezVvcv5+diuVJcfpYM/Fq neG0cg4/caLOZ8oUUg4ql4PbYUMwEELVV56G0dj57GOSd0E1iyA9n4ZIGy/bOMrXvEK08j+R0Fs7E 2YcOWDBYJ+1kFacSEzPR1V3SVqLEQFX3Evm+fT7L6NUCR+MIPxVrnMo7rilLyeOuDfPPbCaDrZOda 0GNyZSsH5zx47vFNS9RA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1polj1-002KBS-1b; Tue, 18 Apr 2023 13:50:27 +0000 Received: from dfw.source.kernel.org ([2604:1380:4641:c500::1]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1polio-002K7H-2j for linux-arm-kernel@lists.infradead.org; Tue, 18 Apr 2023 13:50:16 +0000 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 6ADB562F5C; 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230418_065014_960206_67ED00A6 X-CRM114-Status: GOOD ( 13.05 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13215744 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E83F7C6FD18 for ; Tue, 18 Apr 2023 13:51:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=h9gMiDKHsjaU1Ay4CBpT+0Ehp1+cGcBHBUMw9GTwblY=; b=2ll1K1kOgx+2w0 IlqCiHiYnYxE9qNDHIaNxS26wK7Fh+aQU0u74h3Ows+qRV/BYdL2q7z2EeHgWujKp8TaUZAeooDsQ uCy6EojchitbFs0wy8YDmSv6GCRSMFvGOB2A3CV+H73FFpL55q010RKqtk8b71cAC2vzgZcm3tcj3 C2vChjSvA74hawzuChpsCqU0Ry5i2sZKGbbJlKkRTULlN3yj6muHURVnyQiWklyMP5cGXK/R2H25x 6iQkrKMua6x7p6aBC5EwyA5uH5InN8UqA31kSZaEFi8Sgl1RG3wR3yTN/5/SQEt5ZPmWyOQ5qMAO5 tEHVNEVWf8ZON0BsuPzw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1polj2-002KCG-1n; Tue, 18 Apr 2023 13:50:28 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1poliq-002K8M-2r for linux-arm-kernel@lists.infradead.org; Tue, 18 Apr 2023 13:50:18 +0000 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 563716351A; 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230418_065017_016485_376B2E80 X-CRM114-Status: GOOD ( 22.41 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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);