From patchwork Tue Aug 9 08:09:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 596551 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 63E4EC3F6B0 for ; Tue, 9 Aug 2022 08:10:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238680AbiHIIKv (ORCPT ); Tue, 9 Aug 2022 04:10:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233351AbiHIIKu (ORCPT ); Tue, 9 Aug 2022 04:10:50 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2BA6B7D1 for ; Tue, 9 Aug 2022 01:10:49 -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 39211612EC for ; Tue, 9 Aug 2022 08:10:49 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B4A61C43470; Tue, 9 Aug 2022 08:10:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1660032648; bh=oPI34RZJsbqu67SVjCqjTm3yri4pEDmQ8oGlXGswDt4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c2BgEpnEHRCBU6deIy1tTjY3gDOtzcuHGehaArf0vSVWkk0KVOFB8zVsdHz3HHwdp cCtNY8XfQ+ZuCydfs/xq9meoa06ODEbJHb0W8cqf40Go2Ky0W3aIe5Ir76DpQDOqqw VImjEXS7dRLl5ptHZSRmEOvGorJ8e3HQo8nqK8KkdB/LQ+YMLieQ+YJcZyd+KbV5O3 eH33Ny+Ua7jdM41RgzNNhv8S0z3h22eKVdpfsnAeNV6Din2RISEfBEhet6cuNj883V HguWcbcZ01QJaZndHAm3I7JL6HOnEwcSYRobj4Mz6HOZMyAxy/8T+BC0jyjkQn1CpZ LwdQ8nSDltqZQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel , "James E.J. Bottomley" , Matthew Garrett , Peter Jones , Ilias Apalodimas , Heinrich Schuchardt , AKASHI Takahiro , Palmer Dabbelt , Atish Patra , Arnd Bergmann , Huacai Chen , Lennart Poettering Subject: [PATCH v2 1/6] efi: stub: add some missing boot service prototypes Date: Tue, 9 Aug 2022 10:09:39 +0200 Message-Id: <20220809080944.1119654-2-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220809080944.1119654-1-ardb@kernel.org> References: <20220809080944.1119654-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1680; i=ardb@kernel.org; h=from:subject; bh=oPI34RZJsbqu67SVjCqjTm3yri4pEDmQ8oGlXGswDt4=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBi8hY7ATzyeS13+RsJEB0BDPtDvOIVLLRn/Pnv5naG 1XmCPxCJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYvIWOwAKCRDDTyI5ktmPJLgFDA CbwpnyvgWvP2EVFScqm776+NayZniECezqggB0s1jyWwAhQDx9rODPCeYuJKSXizzQxHM/dVB80/24 DJsjWABXdwy1Kbj5qE7GYpnOT6Xiwuysr8bJolDEuSffE2lOZGFTajxJqjeWBEhieUH9vZQqO2Kta7 YaVtpzwJ70OKdSZ3hFubVVkRWSv1bUN8g8RyZFv4+uAHkYKMU7mx6r35lEYkSbRA0KmULbYSVbHHmC blddw2R6ufT00XGwNbcDQCNwIi5sMWGEKTBn/dOVDDIak029mDtKSUOYy5Ha5IW/FyNeLbsTUVkucn AVpMRdrgUBDM24gUKBskm42zKBHX20HZBI4UNRvXX1bhGl7NM7sJbKvj9XhXH99pJSpdClsGo1VBUP KFalSIwFRn+LOOWtOaEPFCqDz5OOxcPC3UExQPlGb9HDcRRV6xadKVWa87bhU/dPqUX0LbbJosYkyI rIL+yZAQBfmcGuHFnaiwURxpGrPkyIZV+4QbUfFgUogz0= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Define the correct prototypes for the load_image/start_image and install_multiple_protocol_interfaces boot service pointers so we can call them from the EFI zboot code. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efistub.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index ab9e990447d3..33215d7bd276 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -254,8 +254,12 @@ union efi_boot_services { efi_handle_t *); efi_status_t (__efiapi *install_configuration_table)(efi_guid_t *, void *); - void *load_image; - void *start_image; + efi_status_t (__efiapi *load_image)(bool, efi_handle_t, + efi_device_path_protocol_t *, + void *, unsigned long, + efi_handle_t *); + efi_status_t (__efiapi *start_image)(efi_handle_t, unsigned long *, + efi_char16_t **); efi_status_t __noreturn (__efiapi *exit)(efi_handle_t, efi_status_t, unsigned long, @@ -277,8 +281,8 @@ union efi_boot_services { void *locate_handle_buffer; efi_status_t (__efiapi *locate_protocol)(efi_guid_t *, void *, void **); - void *install_multiple_protocol_interfaces; - void *uninstall_multiple_protocol_interfaces; + efi_status_t (__efiapi *install_multiple_protocol_interfaces)(efi_handle_t *, ...); + efi_status_t (__efiapi *uninstall_multiple_protocol_interfaces)(efi_handle_t, ...); void *calculate_crc32; void *copy_mem; void *set_mem; From patchwork Tue Aug 9 08:09:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 596276 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 C50C9C25B06 for ; Tue, 9 Aug 2022 08:10:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236554AbiHIIKy (ORCPT ); Tue, 9 Aug 2022 04:10:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233351AbiHIIKy (ORCPT ); Tue, 9 Aug 2022 04:10:54 -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 0D1A9B7D1 for ; Tue, 9 Aug 2022 01:10:52 -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 88544612EC for ; Tue, 9 Aug 2022 08:10:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 12877C43140; Tue, 9 Aug 2022 08:10:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1660032652; bh=YebYGkVXz0BIYXQ8WMmB082vbKpbUX4LS7xWcvfr/oI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hJLBzjCfsDISxFlHfDgSWbijk5HHggB19Z844zMfMTb+2FBUSJNIUsQJ+v44s+5gN LTQWbZ2U+8Be/pIrn9+JCsE1tEFi+/dO1i8uIfwj3Bg/6eoWBGJdasvlf6Jf1zOQLj U/0GQTWWTRd11muI15Ky9rp6MHiF+ZCg4okRSDVFhgVyD0lw0iXC3/5iLHTHtCBrN9 TE4aiphatR8CJvEHItpNvj20V871EEJMI4HGmxWRc5vBrqXo/Zi4S/fI3DWWV4/vLD VTD046sRZSY9GdrZVfnoBHWIy//3MxuoIW94G5l5tCE6SNOg9GXlZtW6ZhAjLAvAnS 7KQSx7LXXTs7w== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel , "James E.J. Bottomley" , Matthew Garrett , Peter Jones , Ilias Apalodimas , Heinrich Schuchardt , AKASHI Takahiro , Palmer Dabbelt , Atish Patra , Arnd Bergmann , Huacai Chen , Lennart Poettering Subject: [PATCH v2 2/6] efi: stub: split off printk() routines Date: Tue, 9 Aug 2022 10:09:40 +0200 Message-Id: <20220809080944.1119654-3-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220809080944.1119654-1-ardb@kernel.org> References: <20220809080944.1119654-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=9433; i=ardb@kernel.org; h=from:subject; bh=YebYGkVXz0BIYXQ8WMmB082vbKpbUX4LS7xWcvfr/oI=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBi8hY+Q/OizInYfU1uC10/UXxL3iteMblB3xvhNvoS 1C1j/0+JAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYvIWPgAKCRDDTyI5ktmPJMYFC/ 9BaO3qgevL/xuAZ9AWDOyAO5x2sUoJPVVO6fZeJvPvWajP+afeC3RE61YwOYm7HtWMNBnEJDgLDDfE UTuKtrlFf8o48SsCWopbsFIolVTNtZB6Dk5SCRchn6CAAIPVaw27leLq3m45wXivZUA0baFVzuw/mn zruu/f8HMCSax9QpQE5cVDWbxXBqRG2/N9qX6cwOkCxrXMPUWNMcqR0db2w8XcxmUYFyz/S0us5vRT yq//bEzv5sjmOKcPkCI9/iEctRDX1zBHtrD8S8NHBMp2kQAD7QQOL/sFj5eqNIWhHYFURxw5sxsOWk sa7D9WEIrkcwS9+arShVSD/vYyCcqG5Yt6/oATBlSU1lW3GVjYqhyD3bHtYmWWv5hhZ9QDNjdz6pcg +ELKzJcuQhKIOgjbMVBiF79Jdfn6CLBUcNVPZ5FnOAvVzkKMXiRyr/1sR7hgEa+p7DvuSsRNIS3Fn4 yIk4L6z33k2dP6KovA4i43FfmC0/EbTBWdTpMf9g7FGkE= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org We will be using the libstub static library also to build the EFI zboot decompressor, which is a separate binary and does not carry all the dependencies of efi-stub-helper.c, which is where efi_printk() currently lives. So split it off into printk.c so we can incorporate it separately. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/Makefile | 2 +- drivers/firmware/efi/libstub/efi-stub-helper.c | 141 ----------------- drivers/firmware/efi/libstub/printk.c | 158 ++++++++++++++++++++ 3 files changed, 159 insertions(+), 142 deletions(-) diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index d0537573501e..475224be08e1 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -55,7 +55,7 @@ KCOV_INSTRUMENT := n lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ file.o mem.o random.o randomalloc.o pci.o \ skip_spaces.o lib-cmdline.o lib-ctype.o \ - alignedmem.o relocate.o vsprintf.o + alignedmem.o relocate.o vsprintf.o printk.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 3d972061c1b0..45910c834133 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -20,7 +20,6 @@ bool efi_nochunk; bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE); -int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; bool efi_novamap; static bool efi_noinitrd; @@ -32,146 +31,6 @@ bool __pure __efi_soft_reserve_enabled(void) return !efi_nosoftreserve; } -/** - * efi_char16_puts() - Write a UCS-2 encoded string to the console - * @str: UCS-2 encoded string - */ -void efi_char16_puts(efi_char16_t *str) -{ - efi_call_proto(efi_table_attr(efi_system_table, con_out), - output_string, str); -} - -static -u32 utf8_to_utf32(const u8 **s8) -{ - u32 c32; - u8 c0, cx; - size_t clen, i; - - c0 = cx = *(*s8)++; - /* - * The position of the most-significant 0 bit gives us the length of - * a multi-octet encoding. - */ - for (clen = 0; cx & 0x80; ++clen) - cx <<= 1; - /* - * If the 0 bit is in position 8, this is a valid single-octet - * encoding. If the 0 bit is in position 7 or positions 1-3, the - * encoding is invalid. - * In either case, we just return the first octet. - */ - if (clen < 2 || clen > 4) - return c0; - /* Get the bits from the first octet. */ - c32 = cx >> clen--; - for (i = 0; i < clen; ++i) { - /* Trailing octets must have 10 in most significant bits. */ - cx = (*s8)[i] ^ 0x80; - if (cx & 0xc0) - return c0; - c32 = (c32 << 6) | cx; - } - /* - * Check for validity: - * - The character must be in the Unicode range. - * - It must not be a surrogate. - * - It must be encoded using the correct number of octets. - */ - if (c32 > 0x10ffff || - (c32 & 0xf800) == 0xd800 || - clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000)) - return c0; - *s8 += clen; - return c32; -} - -/** - * efi_puts() - Write a UTF-8 encoded string to the console - * @str: UTF-8 encoded string - */ -void efi_puts(const char *str) -{ - efi_char16_t buf[128]; - size_t pos = 0, lim = ARRAY_SIZE(buf); - const u8 *s8 = (const u8 *)str; - u32 c32; - - while (*s8) { - if (*s8 == '\n') - buf[pos++] = L'\r'; - c32 = utf8_to_utf32(&s8); - if (c32 < 0x10000) { - /* Characters in plane 0 use a single word. */ - buf[pos++] = c32; - } else { - /* - * Characters in other planes encode into a surrogate - * pair. - */ - buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10); - buf[pos++] = 0xdc00 + (c32 & 0x3ff); - } - if (*s8 == '\0' || pos >= lim - 2) { - buf[pos] = L'\0'; - efi_char16_puts(buf); - pos = 0; - } - } -} - -/** - * efi_printk() - Print a kernel message - * @fmt: format string - * - * The first letter of the format string is used to determine the logging level - * of the message. If the level is less then the current EFI logging level, the - * message is suppressed. The message will be truncated to 255 bytes. - * - * Return: number of printed characters - */ -int efi_printk(const char *fmt, ...) -{ - char printf_buf[256]; - va_list args; - int printed; - int loglevel = printk_get_level(fmt); - - switch (loglevel) { - case '0' ... '9': - loglevel -= '0'; - break; - default: - /* - * Use loglevel -1 for cases where we just want to print to - * the screen. - */ - loglevel = -1; - break; - } - - if (loglevel >= efi_loglevel) - return 0; - - if (loglevel >= 0) - efi_puts("EFI stub: "); - - fmt = printk_skip_level(fmt); - - va_start(args, fmt); - printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args); - va_end(args); - - efi_puts(printf_buf); - if (printed >= sizeof(printf_buf)) { - efi_puts("[Message truncated]\n"); - return -1; - } - - return printed; -} - /** * efi_parse_options() - Parse EFI command line options * @cmdline: kernel command line diff --git a/drivers/firmware/efi/libstub/printk.c b/drivers/firmware/efi/libstub/printk.c new file mode 100644 index 000000000000..ec09bf895c1a --- /dev/null +++ b/drivers/firmware/efi/libstub/printk.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Helper functions used by the EFI stub on multiple + * architectures. This should be #included by the EFI stub + * implementation files. + * + * Copyright 2011 Intel Corporation; author Matt Fleming + */ + +#include +#include +#include +#include /* For CONSOLE_LOGLEVEL_* */ +#include + +#include "efistub.h" + +int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; + +/** + * efi_char16_puts() - Write a UCS-2 encoded string to the console + * @str: UCS-2 encoded string + */ +void efi_char16_puts(efi_char16_t *str) +{ + efi_call_proto(efi_table_attr(efi_system_table, con_out), + output_string, str); +} + +static +u32 utf8_to_utf32(const u8 **s8) +{ + u32 c32; + u8 c0, cx; + size_t clen, i; + + c0 = cx = *(*s8)++; + /* + * The position of the most-significant 0 bit gives us the length of + * a multi-octet encoding. + */ + for (clen = 0; cx & 0x80; ++clen) + cx <<= 1; + /* + * If the 0 bit is in position 8, this is a valid single-octet + * encoding. If the 0 bit is in position 7 or positions 1-3, the + * encoding is invalid. + * In either case, we just return the first octet. + */ + if (clen < 2 || clen > 4) + return c0; + /* Get the bits from the first octet. */ + c32 = cx >> clen--; + for (i = 0; i < clen; ++i) { + /* Trailing octets must have 10 in most significant bits. */ + cx = (*s8)[i] ^ 0x80; + if (cx & 0xc0) + return c0; + c32 = (c32 << 6) | cx; + } + /* + * Check for validity: + * - The character must be in the Unicode range. + * - It must not be a surrogate. + * - It must be encoded using the correct number of octets. + */ + if (c32 > 0x10ffff || + (c32 & 0xf800) == 0xd800 || + clen != (c32 >= 0x80) + (c32 >= 0x800) + (c32 >= 0x10000)) + return c0; + *s8 += clen; + return c32; +} + +/** + * efi_puts() - Write a UTF-8 encoded string to the console + * @str: UTF-8 encoded string + */ +void efi_puts(const char *str) +{ + efi_char16_t buf[128]; + size_t pos = 0, lim = ARRAY_SIZE(buf); + const u8 *s8 = (const u8 *)str; + u32 c32; + + while (*s8) { + if (*s8 == '\n') + buf[pos++] = L'\r'; + c32 = utf8_to_utf32(&s8); + if (c32 < 0x10000) { + /* Characters in plane 0 use a single word. */ + buf[pos++] = c32; + } else { + /* + * Characters in other planes encode into a surrogate + * pair. + */ + buf[pos++] = (0xd800 - (0x10000 >> 10)) + (c32 >> 10); + buf[pos++] = 0xdc00 + (c32 & 0x3ff); + } + if (*s8 == '\0' || pos >= lim - 2) { + buf[pos] = L'\0'; + efi_char16_puts(buf); + pos = 0; + } + } +} + +/** + * efi_printk() - Print a kernel message + * @fmt: format string + * + * The first letter of the format string is used to determine the logging level + * of the message. If the level is less then the current EFI logging level, the + * message is suppressed. The message will be truncated to 255 bytes. + * + * Return: number of printed characters + */ +int efi_printk(const char *fmt, ...) +{ + char printf_buf[256]; + va_list args; + int printed; + int loglevel = printk_get_level(fmt); + + switch (loglevel) { + case '0' ... '9': + loglevel -= '0'; + break; + default: + /* + * Use loglevel -1 for cases where we just want to print to + * the screen. + */ + loglevel = -1; + break; + } + + if (loglevel >= efi_loglevel) + return 0; + + if (loglevel >= 0) + efi_puts("EFI stub: "); + + fmt = printk_skip_level(fmt); + + va_start(args, fmt); + printed = vsnprintf(printf_buf, sizeof(printf_buf), fmt, args); + va_end(args); + + efi_puts(printf_buf); + if (printed >= sizeof(printf_buf)) { + efi_puts("[Message truncated]\n"); + return -1; + } + + return printed; +} From patchwork Tue Aug 9 08:09:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 596550 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 A46E7C19F2D for ; Tue, 9 Aug 2022 08:10:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236937AbiHIIK6 (ORCPT ); Tue, 9 Aug 2022 04:10:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233351AbiHIIK4 (ORCPT ); Tue, 9 Aug 2022 04:10:56 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CFCEB7D1 for ; Tue, 9 Aug 2022 01:10:56 -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 DE170612EC for ; Tue, 9 Aug 2022 08:10:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64894C43470; Tue, 9 Aug 2022 08:10:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1660032655; bh=osc5+6bshM/GKgDoemiFn7nxKi4gTqJbJp+7vmhIG8w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KniEunSfVTupAv5zA0MJgjHi2cmlKq4iG7owntJc56HAZEAyIG0xWPEefaZpgrsGu JnPdfqdHTxybZM5xhiXKxr6Ub1ezHvBcxQneykuK8Ht9tZSkNYC8mEqQc+0Fp4OjSb 8hyf9yjwEi+BQ0b62uJCTNi1V1P5NYYjnq/rd/l/W/7MjhwJu0ExPpRWSvdvdq2arK cXSNry8NxTx9ve4Njxict7T2Iqc2SJVaL41l1rioOv0jM4JW4DNkSnDRwQIDEkiNhv Cv6sHdFrJH672OmsVX2F0wXDtmhxmaOsbnCcVRWWRVDZIPBF7u48NQsHO5blmQPtKV x542+Pyr4B19Q== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel , "James E.J. Bottomley" , Matthew Garrett , Peter Jones , Ilias Apalodimas , Heinrich Schuchardt , AKASHI Takahiro , Palmer Dabbelt , Atish Patra , Arnd Bergmann , Huacai Chen , Lennart Poettering Subject: [PATCH v2 3/6] efi: stub: move efi_system_table global var into separate object Date: Tue, 9 Aug 2022 10:09:41 +0200 Message-Id: <20220809080944.1119654-4-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220809080944.1119654-1-ardb@kernel.org> References: <20220809080944.1119654-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2047; i=ardb@kernel.org; h=from:subject; bh=osc5+6bshM/GKgDoemiFn7nxKi4gTqJbJp+7vmhIG8w=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBi8hZAmHfnVpMFN8Yq1XZ3Wrk6VajesPmWOdZmWW+Z f2DsQB+JAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYvIWQAAKCRDDTyI5ktmPJE/GC/ wL64pVb/NAUncAME7nAieHMOSaGjvG5eXOlIRL+Gog0WRDwar642ZTIcU5j6bzhy0zux38/FVEOZ+a LSgt9URctnpd37MG2Cg+MbPDdh8hYBhPh1v4VUoPTKua3wCIPYHNGNBNvM51ZQ47/ork1rnBojq34Z a7quYeXEFcJE8U158ayb+5O6IIQ8w1yZvM8pxXywNMSycaXP9N+XUV4sVy4QWrVXe14eBOcFwPiAbv bIXDvKNRCR3JHHoQgf2C+SQuKOAEGd4gtW6K5Iobwf+g4fQo6qmskqwWRUMj7hRt12TIBXhgxseiA1 8Q3FLhfKsAmXD+Vs20GOuhSV4EfVjdko7FT8fYernSw9bHTgPpoUFR1EPvt0JssnVbCZBRtGyZHvMV d5E74Ijm7Z3Qoe8vw7bgLBH75xt4A4Bdz5481P1HS3pCASjX3mlwkBD3GNfbaC9KBwPUeiTo60Easf Ppknhleb6x7P6FOiIT69pfQ4bLlEeGpwBZlcMX5lYo4hs= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org To avoid pulling in the wrong object when using the libstub static library to build the decompressor, define efi_system_table in a separate compilation unit. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/Makefile | 3 ++- drivers/firmware/efi/libstub/efi-stub.c | 2 -- drivers/firmware/efi/libstub/systable.c | 8 ++++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 475224be08e1..a8e26d5a1d14 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -55,7 +55,8 @@ KCOV_INSTRUMENT := n lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ file.o mem.o random.o randomalloc.o pci.o \ skip_spaces.o lib-cmdline.o lib-ctype.o \ - alignedmem.o relocate.o vsprintf.o printk.o + alignedmem.o relocate.o vsprintf.o printk.o \ + systable.o # include the stub's generic dependencies from lib/ when building for ARM/arm64 efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index f515394cce6e..ad179632f99f 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -49,8 +49,6 @@ static u64 virtmap_base = EFI_RT_VIRTUAL_BASE; static bool flat_va_mapping; -const efi_system_table_t *efi_system_table; - static struct screen_info *setup_graphics(void) { efi_guid_t gop_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; diff --git a/drivers/firmware/efi/libstub/systable.c b/drivers/firmware/efi/libstub/systable.c new file mode 100644 index 000000000000..91d016b02f8c --- /dev/null +++ b/drivers/firmware/efi/libstub/systable.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +#include "efistub.h" + +const efi_system_table_t *efi_system_table; From patchwork Tue Aug 9 08:09:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 596275 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 47C7BC19F2D for ; Tue, 9 Aug 2022 08:11:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233351AbiHIILC (ORCPT ); Tue, 9 Aug 2022 04:11:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239000AbiHIILB (ORCPT ); Tue, 9 Aug 2022 04:11:01 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2C51B7D1 for ; Tue, 9 Aug 2022 01:10:59 -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 61F55612F1 for ; Tue, 9 Aug 2022 08:10:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B7CBAC433D7; Tue, 9 Aug 2022 08:10:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1660032658; bh=Mgl35wQ7H8p5ni5yxawy0fLLMwxmayhU0ytRYFv/l2k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZWRGxb2vJzbZNLqWVboJ1XuP/XzAFhxyjZuUOParK03bROC5xvf9UZ5eC1pzSJ4ln 0FSd9RxWDOOY1vhYu4mrBQfQiLy2YDM0BZp7L+wY7mlUUhSqQboLTT/uTGPiBXv8ls hgo+amMU2CRV+p9jufXd0iR6YqMWSxo3MBNitM6m9p8FYnbq9vKC3kTdxE7E5/L78V R8tKEat9jSBkRrawXZKy0FlkEL+7kbWdSlHJsnqJIMP5f+xWr1K/Hxxs5/0nwsHaob mZ3sNOBLeDdth/2EipGmLdite429bGucw4Bft0ub2mHwgsnnhkzsMmgoVbjIfi2vWr 5otnaLp4ok1EQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel , "James E.J. Bottomley" , Matthew Garrett , Peter Jones , Ilias Apalodimas , Heinrich Schuchardt , AKASHI Takahiro , Palmer Dabbelt , Atish Patra , Arnd Bergmann , Huacai Chen , Lennart Poettering Subject: [PATCH v2 4/6] efi: stub: implement generic EFI zboot Date: Tue, 9 Aug 2022 10:09:42 +0200 Message-Id: <20220809080944.1119654-5-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220809080944.1119654-1-ardb@kernel.org> References: <20220809080944.1119654-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=16616; i=ardb@kernel.org; h=from:subject; bh=Mgl35wQ7H8p5ni5yxawy0fLLMwxmayhU0ytRYFv/l2k=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBi8hZClJ9efS4J+RboJHQZ8uPgbipTw7gRfy4zTdU5 uHsJgo+JAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYvIWQgAKCRDDTyI5ktmPJNDpDA CEUkbG22rdb0xsTeHusGurQvtJtGhtfinrXT9rsVm5m8asGP/VmWQMjar+f//URto+xrofuqmgK3rc l2vqp1oBU/tZQVwHI3gMJt/zgXLZTr5+cLcse3kriZPV587bFKrkyd9yUYM+PFKllYmHiMFCZxvD7o KzUkRRw8xORetksQ2JxPsjSCAdgzRQli8AW/UlSo7/U/mFperemkAVwZKJi/lrvs8NGm4uQjlV7pO3 ALklDG9CS7bXjv1Lx7vI+ESTC74eFfxRIR82a3DJUYyZLeDldUBZsp1/+3i/3mUCt0Oj44auDHQ6tj +hKkMoEj1RgbpD7uvq5KBNNSNk85gUgteRBhCk3GulXVXhr9stgMMkFMatVz/VkSeez3hvzEckjqF/ SPTfp5U5b62TL3M8Z0UFtw0W33Ne0rcTY2fkffl/Pj8p4WGAstfO9rBQSEvzkfSBxYvrwUNE0ceLLG N5R/BHS4G/TqaSPRZcSn7hNy+nsysGAfWkl0S7Sr3OGHw= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Implement a minimal EFI app that decompresses the real kernel image and launches it using the firmware's LoadImage and StartImage boot services. This removes the need for any arch-specific hacks. Note that on systems that have UEFI secure boot policies enabled, LoadImage/StartImage require images to be signed, or their hashes known a priori, in order to be permitted to boot. We adopt the same approach as the EFI shim used by the distros, which is to override the security arch protocol implementations used internally by the firmware, permitting the inner, compressed image to be loaded and started after decompression. The outer PE/COFF image will be signed as usual in such cases, preserving the chain of trust. BZIP2 has been omitted from the set of supported compression algorithms, given that its performance is mediocre both in speed and size, and it uses a disproportionate amount of memory. For optimal compression, use LZMA. For the fastest boot speed, use LZO. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/Kconfig | 9 + drivers/firmware/efi/libstub/Makefile | 4 + drivers/firmware/efi/libstub/Makefile.zboot | 30 +++ drivers/firmware/efi/libstub/zboot-header.S | 144 +++++++++++++++ drivers/firmware/efi/libstub/zboot.c | 191 ++++++++++++++++++++ drivers/firmware/efi/libstub/zboot.lds | 41 +++++ include/linux/efi.h | 2 + 7 files changed, 421 insertions(+) diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 6cb7384ad2ac..9ee0944f80bf 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -105,6 +105,15 @@ config EFI_RUNTIME_WRAPPERS config EFI_GENERIC_STUB bool +config EFI_ZBOOT + bool "Enable the generic EFI decompressor" + depends on EFI_GENERIC_STUB + depends on !ARM && !X86 + select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZ4 + select HAVE_KERNEL_LZMA + select HAVE_KERNEL_LZO + config EFI_ARMSTUB_DTB_LOADER bool "Enable the DTB loader" depends on EFI_GENERIC_STUB && !RISCV diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index a8e26d5a1d14..721f948950b8 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -112,8 +112,12 @@ STUBCOPY_RELOC-$(CONFIG_ARM) := R_ARM_ABS # a verification pass to see if any absolute relocations exist in any of the # object files. # +lib-$(CONFIG_EFI_ZBOOT) += zboot.o extra-y := $(lib-y) lib-y := $(patsubst %.o,%.stub.o,$(lib-y)) +lib-$(CONFIG_EFI_ZBOOT) += zboot-header.o +AFLAGS_zboot-header.o += -DZIMAGE_EFI_PATH="\"$(realpath \ + $(objtree)/arch/$(ARCH)/boot/zImage.efi.elf)\"" STUBCOPY_FLAGS-$(CONFIG_ARM64) += --prefix-alloc-sections=.init \ --prefix-symbols=__efistub_ diff --git a/drivers/firmware/efi/libstub/Makefile.zboot b/drivers/firmware/efi/libstub/Makefile.zboot new file mode 100644 index 000000000000..37d95d90db47 --- /dev/null +++ b/drivers/firmware/efi/libstub/Makefile.zboot @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0 + +# to be include'd by arch/$(ARCH)/boot/Makefile after setting +# ZBOOT_PAYLOAD, ZBOOT_BFD_TARGET, ZBOOT_LD_FLAGS and ZBOOT_EXTRA_DEPS + +zimage-method-$(CONFIG_KERNEL_GZIP) := gzip +zimage-method-$(CONFIG_KERNEL_LZ4) := lz4_with_size +zimage-method-$(CONFIG_KERNEL_LZMA) := lzma_with_size +zimage-method-$(CONFIG_KERNEL_LZO) := lzo_with_size + +$(obj)/zImage: $(ZBOOT_PAYLOAD) FORCE + $(call if_changed,$(zimage-method-y)) + +OBJCOPYFLAGS_zImage.o := -I binary -O $(ZBOOT_BFD_TARGET) \ + --rename-section .data=.gzdata,load,alloc,readonly,contents +$(obj)/zImage.o: $(obj)/zImage FORCE + $(call if_changed,objcopy) + +ZBOOT_DEPS := $(ZBOOT_EXTRA_DEPS) $(objtree)/drivers/firmware/efi/libstub/lib.a + +LDFLAGS_zImage.efi.elf := -T $(srctree)/drivers/firmware/efi/libstub/zboot.lds \ + $(ZBOOT_LD_FLAGS) +$(obj)/zImage.efi.elf: $(obj)/zImage.o $(ZBOOT_DEPS) FORCE + $(call if_changed,ld) + +OBJCOPYFLAGS_zImage.efi := -O binary +$(obj)/zImage.efi: $(obj)/zImage.efi.elf FORCE + $(call if_changed,objcopy) + +targets += zImage zImage.o zImage.efi.elf zImage.efi diff --git a/drivers/firmware/efi/libstub/zboot-header.S b/drivers/firmware/efi/libstub/zboot-header.S new file mode 100644 index 000000000000..59ede6f253df --- /dev/null +++ b/drivers/firmware/efi/libstub/zboot-header.S @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include + +#if defined(CONFIG_ARM64) + .set .Lmachine_type, IMAGE_FILE_MACHINE_ARM64 +#elif defined(CONFIG_RISCV) +#ifdef CONFIG_64BIT + .set .Lmachine_type, IMAGE_FILE_MACHINE_RISCV64 +#else + .set .Lmachine_type, IMAGE_FILE_MACHINE_RISCV32 +#endif +#else +#error +#endif + + .section ".head", "a" + .globl __efistub_efi_zboot_header +__efistub_efi_zboot_header: +.Ldoshdr: + .long MZ_MAGIC + .org .Ldoshdr + 0x38 + + // GRUB wants this on arm64 but doesn't (and shouldn't!) care on other + // architectures so let's just put the arm64 magic signature here. + .ascii "ARM\x64" + + .long .Lpehdr - .Ldoshdr + +.Lpehdr: + .long PE_MAGIC + .short .Lmachine_type + .short .Lsection_count + .long 0 + .long 0 + .long 0 + .short .Lsection_table - .Loptional_header + .short IMAGE_FILE_DEBUG_STRIPPED | \ + IMAGE_FILE_EXECUTABLE_IMAGE | \ + IMAGE_FILE_LINE_NUMS_STRIPPED + +.Loptional_header: +#ifdef CONFIG_64BIT + .short PE_OPT_MAGIC_PE32PLUS +#else + .short PE_OPT_MAGIC_PE32 +#endif + .byte 0, 0 + .long _etext - .Lefi_header_end + .long __data_size + .long 0 + .long __efistub_efi_zboot_entry - .Ldoshdr + .long .Lefi_header_end - .Ldoshdr + +#ifdef CONFIG_64BIT + .quad 0 +#else + .long _etext - .Lhead + .long 0 +#endif + .long 4096 + .long 512 + .short 0, 0, 0, 0, 0, 0 + .long 0 + .long _end - .Ldoshdr + + .long .Lefi_header_end - .Ldoshdr + .long 0 + .short IMAGE_SUBSYSTEM_EFI_APPLICATION + .short 0 + .quad 0, 0, 0, 0 + .long 0 + .long (.Lsection_table - .) / 8 + + .quad 0 // ExportTable + .quad 0 // ImportTable + .quad 0 // ResourceTable + .quad 0 // ExceptionTable + .quad 0 // CertificationTable + .quad 0 // BaseRelocationTable +#ifdef CONFIG_DEBUG_EFI + .long .Lefi_debug_table - .Ldoshdr // DebugTable + .long .Lefi_debug_table_size +#endif + +.Lsection_table: + .ascii ".text\0\0\0" + .long _etext - .Lefi_header_end + .long .Lefi_header_end - .Ldoshdr + .long _etext - .Lefi_header_end + .long .Lefi_header_end - .Ldoshdr + + .long 0, 0 + .short 0, 0 + .long IMAGE_SCN_CNT_CODE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE + + .ascii ".data\0\0\0" + .long __data_size + .long _etext - .Ldoshdr + .long __data_rawsize + .long _etext - .Ldoshdr + + .long 0, 0 + .short 0, 0 + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE + + .set .Lsection_count, (. - .Lsection_table) / 40 + +#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 + .long 0 // Unknown + .long 0 // Unknown2 + .long 0 // Unknown3 + + .asciz ZIMAGE_EFI_PATH + + .set .Lefi_debug_entry_size, . - .Lefi_debug_entry +#endif + + .p2align 12 +.Lefi_header_end: + diff --git a/drivers/firmware/efi/libstub/zboot.c b/drivers/firmware/efi/libstub/zboot.c new file mode 100644 index 000000000000..31868b74d152 --- /dev/null +++ b/drivers/firmware/efi/libstub/zboot.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include + +#include "efistub.h" + +#define STATIC static + +static unsigned char zboot_heap[SZ_64K] __aligned(64); +static unsigned long free_mem_ptr, free_mem_end_ptr; + +#if defined(CONFIG_KERNEL_GZIP) +#include "../../../../lib/decompress_inflate.c" +#elif defined(CONFIG_KERNEL_LZ4) +#include "../../../../lib/decompress_unlz4.c" +#elif defined(CONFIG_KERNEL_LZMA) +#include "../../../../lib/decompress_unlzma.c" +#elif defined(CONFIG_KERNEL_LZO) +#include "../../../../lib/decompress_unlzo.c" +#endif + +extern char _gzdata_start[], _gzdata_end[]; +extern u32 uncompressed_size __aligned(1); + +typedef struct efi_security_arch_protocol efi_security_arch_protocol_t; + +typedef efi_status_t +(* __efiapi file_auth_state_fn)(efi_security_arch_protocol_t *, + u32, efi_device_path_protocol_t *); + +struct efi_security_arch_protocol { + file_auth_state_fn file_auth_state; +}; + + +typedef struct efi_security_arch2_protocol efi_security_arch2_protocol_t; + +typedef efi_status_t +(* __efiapi file_auth_fn)(efi_security_arch2_protocol_t *, + efi_device_path_protocol_t *, + void *, unsigned long, bool); + +struct efi_security_arch2_protocol { + file_auth_fn file_auth; +}; + +static file_auth_state_fn prev_file_auth_state; +static file_auth_fn prev_file_auth; + +static efi_status_t __efiapi +file_auth_state_override(efi_security_arch_protocol_t *this, + u32 auth_state, + efi_device_path_protocol_t *file) +{ + prev_file_auth_state(this, auth_state, file); + return EFI_SUCCESS; +} + +static efi_status_t __efiapi +file_auth_override(efi_security_arch2_protocol_t *this, + efi_device_path_protocol_t *file, + void *file_buffer, unsigned long file_size, + bool boot_policy) +{ + prev_file_auth(this, file, file_buffer, file_size, boot_policy); + return EFI_SUCCESS; +} + +static void error(char *x) +{ + efi_err("%s\n", x); +} + +efi_status_t __efiapi efi_zboot_entry(efi_handle_t handle, + efi_system_table_t *systab) +{ + efi_guid_t security_arch = EFI_SECURITY_ARCH_PROTOCOL_GUID; + efi_guid_t security_arch2 = EFI_SECURITY_ARCH2_PROTOCOL_GUID; + efi_guid_t loaded_image = LOADED_IMAGE_PROTOCOL_GUID; + struct efi_security_arch_protocol *sec_proto = NULL; + struct efi_security_arch2_protocol *sec2_proto = NULL; + efi_loaded_image_t *parent, *child; + efi_handle_t child_handle = NULL; + unsigned long image_buffer; + efi_status_t status; + int ret; + + free_mem_ptr = (unsigned long)&zboot_heap; + free_mem_end_ptr = free_mem_ptr + sizeof(zboot_heap); + + efi_system_table = systab; + + efi_info("Entering EFI decompressor\n"); + + status = efi_bs_call(handle_protocol, handle, &loaded_image, + (void **)&parent); + if (status != EFI_SUCCESS) { + efi_err("Failed to locate parent's loaded image protocol\n"); + return status; + } + + status = efi_allocate_pages(uncompressed_size, &image_buffer, ULONG_MAX); + if (status != EFI_SUCCESS) { + efi_err("Failed to allocate memory\n"); + return status; + } + + ret = __decompress(_gzdata_start, _gzdata_end - _gzdata_start, NULL, + NULL, (unsigned char *)image_buffer, 0, NULL, + error); + if (ret < 0) { + efi_err("Decompression failed (ret == %d)\n", ret); + return EFI_LOAD_ERROR; + } + + // + // This is where it becomes slightly nasty: when UEFI secure boot + // policies are in effect, LoadImage() and StartImage() will reject + // unsigned images, in a slightly peculiar and inconsistent way: + // Tiancore's reference implementation will return + // EFI_SECURITY_VIOLATION from LoadImage() if authentication fails, but + // will not unload the image from memory, potentially allowing the + // image to be invoked anyway, by branching to the right offset in the + // image. Other implementations exist that deviate from this behavior, + // and return a fatal error from LoadImage() that does not allow the + // above workaround. In any case, StartImage() only permits starting + // images for which LoadImage() returned EFI_SUCCESS. + // + // Let's take the shim approach here, and manipulate the underlying + // protocol that performs the file authentication. That way, we should + // be able to rely on LoadImage/StartImage on all firmware built from + // Tianocore or derived from it, without dealing with the individual + // quirks. For non-EDK2 based implementations, we really need some kind + // of protocol that can start an image after the signature check has + // failed. + // + + // TODO the protocols below are defined in the PI spec and interoperate + // with the DXE foundation, which EFI firmware may not implement. So we + // need to define a protocol that the firmware will invoke which allows + // us to indicate that the image we are loading should be permitted + // regardless of secure boot restrictions. + + status = efi_bs_call(locate_protocol, &security_arch, NULL, + (void **)&sec_proto); + if (status == EFI_SUCCESS) { + prev_file_auth_state = sec_proto->file_auth_state; + sec_proto->file_auth_state = file_auth_state_override; + } + + status = efi_bs_call(locate_protocol, &security_arch2, NULL, + (void **)&sec2_proto); + if (status == EFI_SUCCESS) { + prev_file_auth = sec2_proto->file_auth; + sec2_proto->file_auth = file_auth_override; + } + + status = efi_bs_call(load_image, true, handle, NULL, + (void *)image_buffer, uncompressed_size, + &child_handle); + if (status != EFI_SUCCESS) { + efi_err("Failed to load image: %lx\n", status); + return status; + } + + status = efi_bs_call(handle_protocol, child_handle, &loaded_image, + (void **)&child); + if (status != EFI_SUCCESS) { + efi_err("Failed to locate child's loaded image protocol\n"); + return status; + } + + // Copy the kernel command line + child->load_options = parent->load_options; + child->load_options_size = parent->load_options_size; + + status = efi_bs_call(start_image, child_handle, NULL, NULL); + if (status != EFI_SUCCESS) { + efi_err("StartImage() return with error: %lx\n", status); + return status; + } + + if (sec_proto != NULL) + sec_proto->file_auth_state = prev_file_auth_state; + if (sec2_proto != NULL) + sec2_proto->file_auth = prev_file_auth; + + return EFI_SUCCESS; +} diff --git a/drivers/firmware/efi/libstub/zboot.lds b/drivers/firmware/efi/libstub/zboot.lds new file mode 100644 index 000000000000..f7721b2c1e0e --- /dev/null +++ b/drivers/firmware/efi/libstub/zboot.lds @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +ENTRY(__efistub_efi_zboot_header); + +SECTIONS +{ + .text : ALIGN(4096) { + *(.head) + *(.text* .init.text*) + } + + .rodata : ALIGN(8) { + __efistub__gzdata_start = .; + *(.gzdata) + __efistub__gzdata_end = .; + *(.rodata* .init.rodata* .srodata*) + _etext = ALIGN(4096); + . = _etext; + } + + .data : ALIGN(4096) { + *(.data* .init.data*) + _edata = ALIGN(512); + . = _edata; + } + + .bss : { + *(.bss* .init.bss*) + _end = ALIGN(512); + . = _end; + } + + /DISCARD/ : { + *(__ksymtab_strings ___ksymtab+*) + } +} + +PROVIDE(__efistub_uncompressed_size = __efistub__gzdata_end - 4); + +PROVIDE(__data_rawsize = ABSOLUTE(_edata - _etext)); +PROVIDE(__data_size = ABSOLUTE(_end - _etext)); diff --git a/include/linux/efi.h b/include/linux/efi.h index 75f16e9bc0c0..07f17e2c5f69 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -387,6 +387,8 @@ void efi_native_runtime_setup(void); #define EFI_RT_PROPERTIES_TABLE_GUID EFI_GUID(0xeb66918a, 0x7eef, 0x402a, 0x84, 0x2e, 0x93, 0x1d, 0x21, 0xc3, 0x8a, 0xe9) #define EFI_DXE_SERVICES_TABLE_GUID EFI_GUID(0x05ad34ba, 0x6f02, 0x4214, 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9) +#define EFI_SECURITY_ARCH_PROTOCOL_GUID EFI_GUID(0xA46423E3, 0x4617, 0x49f1, 0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39) +#define EFI_SECURITY_ARCH2_PROTOCOL_GUID EFI_GUID(0x94ab2f58, 0x1438, 0x4ef1, 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68) #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) From patchwork Tue Aug 9 08:09:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 596549 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 D1783C25B07 for ; Tue, 9 Aug 2022 08:11:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239056AbiHIILE (ORCPT ); Tue, 9 Aug 2022 04:11:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239000AbiHIILD (ORCPT ); Tue, 9 Aug 2022 04:11:03 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2820FB7D1 for ; Tue, 9 Aug 2022 01:11:03 -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 B98A7612E4 for ; Tue, 9 Aug 2022 08:11:02 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 414FAC43141; Tue, 9 Aug 2022 08:10:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1660032662; bh=0wxGhJZU/zdWw8HRNTrsKFaHxjI9/9W09E4vTFt5wZs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rLmJQIjlAU4BGGQPvb3EUi7CBXdI2iILDNp/6i9x5BrSVVk3cHZYoXSqGEsQTghxN U+lbpoJBFJPwzM1zj6sojAJ0rUPxzyCgCaHNFU2b892yJxC2gUubFC5P5U+rGklW4I Ra7KA0fL5LwYlponAsO9dufsvVDcC8CvCF9ZBtFgay70qc4hXgre7gZz8oBZTKExB1 Sbqja4naiP0JmaRS6yxMB2fSqwQhcdMU5ZzpwvpM75mwlmGWQCULkwsFHOxkT5LnQJ 31HAh1+TKOzMocp4IFj+C0w1SKJD4xFcAjX7zWwJtUCjwBxJrtwTbjjD/aXgeLGTPA ZgQeKmPBJaNlg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel , "James E.J. Bottomley" , Matthew Garrett , Peter Jones , Ilias Apalodimas , Heinrich Schuchardt , AKASHI Takahiro , Palmer Dabbelt , Atish Patra , Arnd Bergmann , Huacai Chen , Lennart Poettering Subject: [PATCH v2 5/6] arm64: efi: enable generic EFI compressed boot Date: Tue, 9 Aug 2022 10:09:43 +0200 Message-Id: <20220809080944.1119654-6-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220809080944.1119654-1-ardb@kernel.org> References: <20220809080944.1119654-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1465; i=ardb@kernel.org; h=from:subject; bh=0wxGhJZU/zdWw8HRNTrsKFaHxjI9/9W09E4vTFt5wZs=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBi8hZE/pHyMam6oID6jHufFqjjsmWunFFPL94BweIA 9ln0bC+JAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYvIWRAAKCRDDTyI5ktmPJOyNC/ 9PD51wW5EkYDZ55n7btMX7VIe2eu42yvHbXO+QUvmE0obi5LTdu4ZIbX6FHg4Ts7H+MOsWRSsyNNB2 eY8vENrnJnkJ3UC8Prb5OeJUKroOkrSCFoLkOBzQ8LEPSNR0yHC7DS0av770nVYVPvvozmWtcQtT4p y6eG4OMjVNuhwN14J0eAaD+GJ0P58SFlUDa/54lnEVhJGWiT8f9tBYJr5eh6sjoN+sa1xvNt5bCzNm YXMQgfpxnbKkWCj2zQJrxChGZirD7kO5nift7S8+KRYc5A4Jkx9tIvAxdpfDLTsHY+KmP1uFCUuJCS rPoqxpZvwF/1JpjHmzvFR2u0ZqVeqAokVz+CBxmN83dAmHST2vyevjcdlFAnAxvaNP5R61zknKxhLB 3j1KZrKZWq8VcTiQWDg7Z4D3ujGsp3JoGX8wotx+0+/OEsgd415yqYTjPTLlv0t5moJe0afylkPfSE d00j56B+kkWwr8S3Li8Q/4EQBDLvPChhHaW+HH7inFffw= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Wire up the generic EFI zboot support for arm64. Signed-off-by: Ard Biesheuvel --- arch/arm64/Makefile | 5 +++++ arch/arm64/boot/Makefile | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 6d9d4a58b898..ad4f849b91e8 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -162,6 +162,11 @@ Image: vmlinux Image.%: Image $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +ifneq ($(CONFIG_EFI_ZBOOT),) +zImage.efi: Image + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +endif + install: KBUILD_IMAGE := $(boot)/Image install zinstall: $(call cmd,install) diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile index a0e3dedd2883..08fcd39ae808 100644 --- a/arch/arm64/boot/Makefile +++ b/arch/arm64/boot/Makefile @@ -38,3 +38,15 @@ $(obj)/Image.lzo: $(obj)/Image FORCE $(obj)/Image.zst: $(obj)/Image FORCE $(call if_changed,zstd) + +ZBOOT_PAYLOAD := $(obj)/Image +ZBOOT_BFD_TARGET := elf64-littleaarch64 +ZBOOT_LD_FLAGS := --defsym=__efistub_strnlen=__pi_strnlen \ + --defsym=__efistub_memmove=__pi_memmove \ + --defsym=__efistub_memcpy=__pi_memcpy \ + --defsym=__efistub_memset=__pi_memset + +ZBOOT_EXTRA_OBJS := memcpy.o memset.o strnlen.o +ZBOOT_EXTRA_DEPS := $(addprefix $(objtree)/arch/arm64/lib/,$(ZBOOT_EXTRA_OBJS)) + +include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot From patchwork Tue Aug 9 08:09:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 596274 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 5D60CC19F2D for ; Tue, 9 Aug 2022 08:11:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239000AbiHIILL (ORCPT ); Tue, 9 Aug 2022 04:11:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239093AbiHIILK (ORCPT ); Tue, 9 Aug 2022 04:11:10 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42478B7D1 for ; Tue, 9 Aug 2022 01:11:08 -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 ams.source.kernel.org (Postfix) with ESMTPS id C8D80B811E0 for ; Tue, 9 Aug 2022 08:11:06 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 92C3AC433B5; Tue, 9 Aug 2022 08:11:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1660032665; bh=0HGizh+6WTk/QYodTT+bl2etkYKDNHiWCQesR+ZiuPE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lLpOFbjiH0gJipvClu/2rhmb+Cozywih1hBUgQRfThgwaC/QwITVzx0CFEuiirsGo 9VQX+hes0nPvtcIimXbewjYIcwnwnaMy2HspJ+n9Hz3IyEyxbuvvLDJdSxUsqeHB68 Y8pBeT10e0J7G/WCNJIqJLp/jGWP4CwmdVlJ4luQrwJHo917GEaQHW58fd5t32rykY jSmsJu5jBLQaA7Dv3WzufKVSv3zoFkTTUCJKB7c26or2ssDUxuIX/X5xarZM9zpxcU J7S10Pc1+oHGwpAN33k1HgZ1o3w9qFYkqf3W2TR+9L7sFkOQQ464hG/jtaWtgVZ1P1 IkyWPyEyYuxWQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: catalin.marinas@arm.com, will@kernel.org, Ard Biesheuvel , "James E.J. Bottomley" , Matthew Garrett , Peter Jones , Ilias Apalodimas , Heinrich Schuchardt , AKASHI Takahiro , Palmer Dabbelt , Atish Patra , Arnd Bergmann , Huacai Chen , Lennart Poettering Subject: [PATCH v2 6/6] riscv: efi: enable generic EFI compressed boot Date: Tue, 9 Aug 2022 10:09:44 +0200 Message-Id: <20220809080944.1119654-7-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220809080944.1119654-1-ardb@kernel.org> References: <20220809080944.1119654-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1555; i=ardb@kernel.org; h=from:subject; bh=0HGizh+6WTk/QYodTT+bl2etkYKDNHiWCQesR+ZiuPE=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBi8hZG4yeSVhX+lZWCL9jaXmjxJ3Ka4jm4YSufGjCa 8fIZOjKJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYvIWRgAKCRDDTyI5ktmPJBe4C/ 4yQVL6p6LlS2HXP2Z1a4lfvRvcFQBwxyE97zrs19a/Wl0KqF/GXGsyMhF8ZgcTyYVACg+0rBCS505K sTHj9S//QR+gg+d15ja5jG+TfFdndfITZ8uZZHTyUAphFLdStiYAsXRK58NXlXXGlUMGc892YnE/G3 /s2Ae6Aq/S+eztEXFMM6g/isy36Z/KWjC8BToyeMc8NqjuK9i8mochX7s4cybNBqlDrEITB+npxL7x Dn1Je5DnzqYJleIiaiYcrdJbWNIN/hfPIVDOTv8o6S8FQfTWfY+xEck9wIwBcTiJodRpaM+uRfl0tE iy7JJtqKjG+yjnbeLrl3cTyj/ANTXIYNkXN9fbzWyQfjx6X2oCiEzYO12BPbTpeSOQMnfUgmtzYBRs xB7khZ5B7kwyvbhCAGRcewXjhq9DjIUkJW/qR1nLlxfJo9Ji1W+kXMOX2uuI25Dgm9Y3QhmErX2Bz+ NcsHghpnJusPfAvjzeIGwp2GhF5pwSVE60EyvU9Gp32I0= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Wire up the generic EFI zboot support for RISC-V. Signed-off-by: Ard Biesheuvel Acked-by: Palmer Dabbelt --- arch/riscv/Makefile | 5 +++++ arch/riscv/boot/Makefile | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 81029d40a672..c30ea65ec877 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -142,6 +142,11 @@ $(BOOT_TARGETS): vmlinux Image.%: Image $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +ifneq ($(CONFIG_EFI_ZBOOT),) +zImage.efi: Image + $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ +endif + install: KBUILD_IMAGE := $(boot)/Image zinstall: KBUILD_IMAGE := $(boot)/Image.gz install zinstall: diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile index becd0621071c..60cd319685ea 100644 --- a/arch/riscv/boot/Makefile +++ b/arch/riscv/boot/Makefile @@ -58,3 +58,17 @@ $(obj)/Image.lzo: $(obj)/Image FORCE $(obj)/loader.bin: $(obj)/loader FORCE $(call if_changed,objcopy) + +ZBOOT_PAYLOAD := $(obj)/Image +ZBOOT_BFD_TARGET := elf$(BITS)-littleriscv +ZBOOT_LD_FLAGS := --defsym=__efistub_strnlen=strnlen \ + --defsym=__efistub_memmove=memmove \ + --defsym=__efistub_memcpy=memcpy \ + --defsym=__efistub_memset=memset + +ZBOOT_EXTRA_OBJS := memcpy.o memset.o memmove.o +ZBOOT_EXTRA_DEPS := $(objtree)/lib/string.o \ + $(objtree)/lib/ctype.o \ + $(addprefix $(objtree)/arch/riscv/lib/,$(ZBOOT_EXTRA_OBJS)) + +include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot