From patchwork Sat Jul 22 12:38:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Ghiti X-Patchwork-Id: 705494 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 77A70EB64DA for ; Sat, 22 Jul 2023 12:40:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229945AbjGVMkB (ORCPT ); Sat, 22 Jul 2023 08:40:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229503AbjGVMkB (ORCPT ); Sat, 22 Jul 2023 08:40:01 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82AAC10DE for ; Sat, 22 Jul 2023 05:39:59 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-31751d7d96eso31109f8f.1 for ; Sat, 22 Jul 2023 05:39:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20221208.gappssmtp.com; s=20221208; t=1690029598; x=1690634398; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=totAZSGL3sMvt7aEqkeHA/bfBbkIFO3TpIoyWFj1SaE=; b=BMS7FVogFjDwK6CyS5mfrgYNX/fe3k2uNhun1aswU0FWtgtmcvBIBBlWq1xFFe33Go GlpZHAjIhhbpO8B+uTMYd3Jfr6loKh15suhBJjH4fqj+CXGMV+u+7Tn+SeK3RYSBXgbc Jt8uQutGlRZ2seyFGF4zYPgmoRHNo+PLFSSUcvMIyPqwhRr1nBxku3ODUf8dLGHTtf/F EmB87sf+depdlzEMxQlbWaxaIXcXamTBjnkKs+9XtrS0vejQxEwNScTbAmujIZUUhL2p Pyaeg9C+sv5EbCcxaSEBvLffw8f/LCSpIGDmIoNeoYDI/g49lGHxF6r87WhVaseAZiZL vOCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690029598; x=1690634398; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=totAZSGL3sMvt7aEqkeHA/bfBbkIFO3TpIoyWFj1SaE=; b=TlxYA0uDnoolVJHt6QrZ4l1NkY4DeT8Sds5c+GVI3UnY2qk/Z07FiuQdlV8XYbD2+J Wcn8XD56U/GE7dL7l8dgL4GjIrmHfEvTeTxORPGzuA4K0cAnKUvzjl2pXzrsc/hsqb8s V1i4CW9kUG8QFz5ZlKGrRJWljK42nNHBM8w8ZgIHHMrmqX2z9Iw50hvFsGDFZsHvHWRk vWl20FmbANAWT+sn9g5gg2U9NpfWAEU4+0pKS2nVwcPdKK3LiN9RiRZAUoDFlN1pYSCH R/MEY/TzJ6BSW3ibA8iT6Ks5KPXhTUz6ErNOZg3pZrQRp3EazUlIO5Q1l8mj/MkBDyyi iTog== X-Gm-Message-State: ABy/qLYSBIfSNXfrO1/nxjtmB4onMUuGi9Zc6oOlHUeu6BXx/gro4nhX WDche4PReQtNmFlHrKAJd9UR2w== X-Google-Smtp-Source: APBJJlG9MnPrBPJXDtJr5W/Uhd9rxs7DINSM3nxcH84zB1voHX3gDE66L6paDNTZqW8K6M4irYrCBQ== X-Received: by 2002:a5d:45c1:0:b0:314:49d2:aaab with SMTP id b1-20020a5d45c1000000b0031449d2aaabmr3675330wrs.8.1690029597978; Sat, 22 Jul 2023 05:39:57 -0700 (PDT) Received: from alex-rivos.ba.rivosinc.com (amontpellier-656-1-456-62.w92-145.abo.wanadoo.fr. [92.145.124.62]) by smtp.gmail.com with ESMTPSA id m24-20020a056000181800b003143ac73fd0sm6876454wrh.1.2023.07.22.05.39.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Jul 2023 05:39:57 -0700 (PDT) From: Alexandre Ghiti To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Ard Biesheuvel , Kees Cook , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Alexandre Ghiti Subject: [PATCH v6 1/5] riscv: Introduce virtual kernel mapping KASLR Date: Sat, 22 Jul 2023 14:38:46 +0200 Message-Id: <20230722123850.634544-2-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230722123850.634544-1-alexghiti@rivosinc.com> References: <20230722123850.634544-1-alexghiti@rivosinc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org KASLR implementation relies on a relocatable kernel so that we can move the kernel mapping. The seed needed to virtually move the kernel is taken from the device tree, so we rely on the bootloader to provide a correct seed. Zkr could be used unconditionnally instead if implemented, but that's for another patch. Signed-off-by: Alexandre Ghiti --- arch/riscv/Kconfig | 19 +++++++++++++++ arch/riscv/include/asm/page.h | 3 +++ arch/riscv/kernel/pi/Makefile | 2 +- arch/riscv/kernel/pi/cmdline_early.c | 13 ++++++++++ arch/riscv/kernel/pi/fdt_early.c | 30 +++++++++++++++++++++++ arch/riscv/mm/init.c | 36 +++++++++++++++++++++++++++- 6 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 arch/riscv/kernel/pi/fdt_early.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 4c07b9189c86..6a606d5b74c6 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -719,6 +719,25 @@ config RELOCATABLE If unsure, say N. +config RANDOMIZE_BASE + bool "Randomize the address of the kernel image" + select RELOCATABLE + depends on MMU && 64BIT && !XIP_KERNEL + help + Randomizes the virtual address at which the kernel image is + loaded, as a security feature that deters exploit attempts + relying on knowledge of the location of kernel internals. + + It is the bootloader's job to provide entropy, by passing a + random u64 value in /chosen/kaslr-seed at kernel entry. + + When booting via the UEFI stub, it will invoke the firmware's + EFI_RNG_PROTOCOL implementation (if available) to supply entropy + to the kernel proper. In addition, it will randomise the physical + location of the kernel Image as well. + + If unsure, say N. + endmenu # "Kernel features" menu "Boot options" diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h index b55ba20903ec..5488ecc337b6 100644 --- a/arch/riscv/include/asm/page.h +++ b/arch/riscv/include/asm/page.h @@ -106,6 +106,7 @@ typedef struct page *pgtable_t; struct kernel_mapping { unsigned long page_offset; unsigned long virt_addr; + unsigned long virt_offset; uintptr_t phys_addr; uintptr_t size; /* Offset between linear mapping virtual address and kernel load address */ @@ -185,6 +186,8 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x); #define sym_to_pfn(x) __phys_to_pfn(__pa_symbol(x)) +unsigned long kaslr_offset(void); + #endif /* __ASSEMBLY__ */ #define virt_addr_valid(vaddr) ({ \ diff --git a/arch/riscv/kernel/pi/Makefile b/arch/riscv/kernel/pi/Makefile index 7b593d44c712..07915dc9279e 100644 --- a/arch/riscv/kernel/pi/Makefile +++ b/arch/riscv/kernel/pi/Makefile @@ -35,5 +35,5 @@ $(obj)/string.o: $(srctree)/lib/string.c FORCE $(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE $(call if_changed_rule,cc_o_c) -obj-y := cmdline_early.pi.o string.pi.o ctype.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o +obj-y := cmdline_early.pi.o fdt_early.pi.o string.pi.o ctype.pi.o lib-fdt.pi.o lib-fdt_ro.pi.o extra-y := $(patsubst %.pi.o,%.o,$(obj-y)) diff --git a/arch/riscv/kernel/pi/cmdline_early.c b/arch/riscv/kernel/pi/cmdline_early.c index 05652d13c746..68e786c84c94 100644 --- a/arch/riscv/kernel/pi/cmdline_early.c +++ b/arch/riscv/kernel/pi/cmdline_early.c @@ -14,6 +14,7 @@ static char early_cmdline[COMMAND_LINE_SIZE]; * LLVM complain because the function is actually unused in this file). */ u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa); +bool set_nokaslr_from_cmdline(uintptr_t dtb_pa); static char *get_early_cmdline(uintptr_t dtb_pa) { @@ -60,3 +61,15 @@ u64 set_satp_mode_from_cmdline(uintptr_t dtb_pa) return match_noXlvl(cmdline); } + +static bool match_nokaslr(char *cmdline) +{ + return strstr(cmdline, "nokaslr"); +} + +bool set_nokaslr_from_cmdline(uintptr_t dtb_pa) +{ + char *cmdline = get_early_cmdline(dtb_pa); + + return match_nokaslr(cmdline); +} diff --git a/arch/riscv/kernel/pi/fdt_early.c b/arch/riscv/kernel/pi/fdt_early.c new file mode 100644 index 000000000000..899610e042ab --- /dev/null +++ b/arch/riscv/kernel/pi/fdt_early.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include +#include + +/* + * Declare the functions that are exported (but prefixed) here so that LLVM + * does not complain it lacks the 'static' keyword (which, if added, makes + * LLVM complain because the function is actually unused in this file). + */ +u64 get_kaslr_seed(uintptr_t dtb_pa); + +u64 get_kaslr_seed(uintptr_t dtb_pa) +{ + int node, len; + fdt64_t *prop; + u64 ret; + + node = fdt_path_offset((void *)dtb_pa, "/chosen"); + if (node < 0) + return 0; + + prop = fdt_getprop_w((void *)dtb_pa, node, "kaslr-seed", &len); + if (!prop || len != sizeof(u64)) + return 0; + + ret = fdt64_to_cpu(*prop); + *prop = 0; + return ret; +} diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c index 70fb31960b63..ff926531236e 100644 --- a/arch/riscv/mm/init.c +++ b/arch/riscv/mm/init.c @@ -1012,11 +1012,45 @@ static void __init pt_ops_set_late(void) #endif } +#ifdef CONFIG_RANDOMIZE_BASE +extern bool __init __pi_set_nokaslr_from_cmdline(uintptr_t dtb_pa); +extern u64 __init __pi_get_kaslr_seed(uintptr_t dtb_pa); + +static int __init print_nokaslr(char *p) +{ + pr_info("Disabled KASLR"); + return 0; +} +early_param("nokaslr", print_nokaslr); + +unsigned long kaslr_offset(void) +{ + return kernel_map.virt_offset; +} +#endif + asmlinkage void __init setup_vm(uintptr_t dtb_pa) { pmd_t __maybe_unused fix_bmap_spmd, fix_bmap_epmd; - kernel_map.virt_addr = KERNEL_LINK_ADDR; +#ifdef CONFIG_RANDOMIZE_BASE + if (!__pi_set_nokaslr_from_cmdline(dtb_pa)) { + u64 kaslr_seed = __pi_get_kaslr_seed(dtb_pa); + u32 kernel_size = (uintptr_t)(&_end) - (uintptr_t)(&_start); + u32 nr_pos; + + /* + * Compute the number of positions available: we are limited + * by the early page table that only has one PUD and we must + * be aligned on PMD_SIZE. + */ + nr_pos = (PUD_SIZE - kernel_size) / PMD_SIZE; + + kernel_map.virt_offset = (kaslr_seed % nr_pos) * PMD_SIZE; + } +#endif + + kernel_map.virt_addr = KERNEL_LINK_ADDR + kernel_map.virt_offset; kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); #ifdef CONFIG_XIP_KERNEL From patchwork Sat Jul 22 12:38:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Ghiti X-Patchwork-Id: 705675 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 01C59EB64DA for ; Sat, 22 Jul 2023 12:41:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229746AbjGVMlC (ORCPT ); Sat, 22 Jul 2023 08:41:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50720 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229702AbjGVMlB (ORCPT ); Sat, 22 Jul 2023 08:41:01 -0400 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8705210F4 for ; Sat, 22 Jul 2023 05:41:00 -0700 (PDT) Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-3fd190065a8so25963185e9.3 for ; Sat, 22 Jul 2023 05:41:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20221208.gappssmtp.com; s=20221208; t=1690029659; x=1690634459; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cxS6XaVGyfGeiOx9hXopxfMKjoMTvLr9eO536Fwx3rg=; b=ubHJsOakNyi6ANYSEfY1jfibGRvwTsZC06/UPIVijfttHEqAybPhZWsu6n+csh9e0l KaIDc/ee0jK34IeIOvDhwfUvuorT/jUT+Lc3zNxBn+AFfH+l6yOjUQS6Rd2/e9MeozK8 jR6YwmPhQ5kiYHNZBD01SLTO+1i4GVi5HibdyOu1QDcm7enIRNuwvCmftfPhFB4ORToz C3U1P2sZ72Wp31FcMQjOrO914SUZBYVecMSN8Qop2CKKpKdGOgRcP2cjNUw+bUa13u7l pcgT1XbQw+oZgWUOaur9xb2fkMtbRtf+60eB0JYS02Rjcnqsw6yCAIkTP8eryqK7lSVB wLfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690029659; x=1690634459; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cxS6XaVGyfGeiOx9hXopxfMKjoMTvLr9eO536Fwx3rg=; b=bWYTuiMLcVLV63LfXf3/rJqIqGhYSqe95jftHe7v8M5j48mYMth0yYlzRBmSxrk3r4 xJflGXBDBuQxfiYOUnOMvnAROqc08hh61pAHXBfxa5AnuRzpmR9zO9pdG9ayw8D11SM/ 6QD0Ntf1UOkWjH4fozrZPgPsdKb0mEwW7g8wsnSlIxdFnnUNjBIqChMkjsT8bbq4H7JA UueUYvCEMTxbTp4EW54jqtpn2DF3GhWpZqRn0p2yDhUklHsSR4sl4DtcKjr0xV48dYO2 zE66+GMn0cCbMprLBMoTsnmYTxYfFCRmFHXMiRc2MT6kx8Jzr/hnneiAd2jcWiMe5Vto oU8A== X-Gm-Message-State: ABy/qLbpteNZI7l7GzZ2C73UOdt35Ws5TsYIg2k8fvVq1KfmUsHbjnmq CgChrr8GZbYrvCAzJT1+AZqTVg== X-Google-Smtp-Source: APBJJlHszG7MkK5M/s+gCn2cPnro3+GaotN/R+BKeRaTosXlQG7ZToDZHwzuzw4UhADn6GJDjqPH2w== X-Received: by 2002:a7b:ca52:0:b0:3f6:1474:905 with SMTP id m18-20020a7bca52000000b003f614740905mr3713142wml.29.1690029658973; Sat, 22 Jul 2023 05:40:58 -0700 (PDT) Received: from alex-rivos.ba.rivosinc.com (amontpellier-656-1-456-62.w92-145.abo.wanadoo.fr. [92.145.124.62]) by smtp.gmail.com with ESMTPSA id p24-20020a1c7418000000b003fc07e17d4esm7988080wmc.2.2023.07.22.05.40.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Jul 2023 05:40:58 -0700 (PDT) From: Alexandre Ghiti To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Ard Biesheuvel , Kees Cook , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Alexandre Ghiti , Zong Li Subject: [PATCH v6 2/5] riscv: Dump out kernel offset information on panic Date: Sat, 22 Jul 2023 14:38:47 +0200 Message-Id: <20230722123850.634544-3-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230722123850.634544-1-alexghiti@rivosinc.com> References: <20230722123850.634544-1-alexghiti@rivosinc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Dump out the KASLR virtual kernel offset when panic to help debug kernel. Signed-off-by: Zong Li Signed-off-by: Alexandre Ghiti --- arch/riscv/kernel/setup.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index 971fe776e2f8..0fb5a26ca4cc 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -341,3 +342,27 @@ void free_initmem(void) free_initmem_default(POISON_FREE_INITMEM); } + +static int dump_kernel_offset(struct notifier_block *self, + unsigned long v, void *p) +{ + pr_emerg("Kernel Offset: 0x%lx from 0x%lx\n", + kernel_map.virt_offset, + KERNEL_LINK_ADDR); + + return 0; +} + +static struct notifier_block kernel_offset_notifier = { + .notifier_call = dump_kernel_offset +}; + +static int __init register_kernel_offset_dumper(void) +{ + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) + atomic_notifier_chain_register(&panic_notifier_list, + &kernel_offset_notifier); + + return 0; +} +device_initcall(register_kernel_offset_dumper); From patchwork Sat Jul 22 12:38:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexandre Ghiti X-Patchwork-Id: 705493 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 D8F1CEB64DA for ; Sat, 22 Jul 2023 12:42:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230297AbjGVMmE (ORCPT ); Sat, 22 Jul 2023 08:42:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229643AbjGVMmD (ORCPT ); Sat, 22 Jul 2023 08:42:03 -0400 Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5DF0010F5 for ; Sat, 22 Jul 2023 05:42:01 -0700 (PDT) Received: by mail-wm1-x330.google.com with SMTP id 5b1f17b1804b1-3fbfa811667so23637665e9.1 for ; Sat, 22 Jul 2023 05:42:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20221208.gappssmtp.com; s=20221208; t=1690029720; x=1690634520; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+mzz7+cmo7mG0EjTGePf51Ll6Zdd1gZGMKR3whiCyXs=; b=V96TMuxzudRhcGO/ZzQURbancsr5lKEHHBYSmn0kZqALCnTYGBt7N4G1iEsoR+Yekd smhceP2BChWnvJEr+/BjRf0ivPk/DG2KEKHi1qne5UgfIa6encaUClnG5uFPUgJMMpOy 9/PK/doiMTFKxoAp+ChEFoQChQtEyAcPwruDqxliXTg3/1Xx7iFIUpzMaicoRmWe2yLq BkxM1RPuaM6PhOBx/1nBLZNffEklYgeyOlvCeowGZ8tFZKTTo41f8B9l5wh+1JfNaMkY GYyH7cwskMy6Hzl8UyTMwDzQAPH620WMZjclV58qyllqLw19MGecyPtEzCsYA+rE6X9s trBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690029720; x=1690634520; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+mzz7+cmo7mG0EjTGePf51Ll6Zdd1gZGMKR3whiCyXs=; b=I+51Al/EsnSf/lOV9w0grXw8WfDgNvwNxW+KCWkukAThSm0R0THdCmiPNmYB91ZVgM Tx0CgpNymmUW8XgDfr+ewMQKXbsxveKOCO3Ku5RHoIw/Jl1m+oovq81lwtJ4eReLDp0o cI9xWHIscedvLGIo1wHNCc2IBjTuqIhdTD3OThhRzcKErqax5QoUWzFa99l1kxvCdIwB dXq8St85oqwR5EfqgYKsxq5yMBIwuGa118PeLQxf8BSGANYwlu4M8aBcj4aCTiE3hHLr EvKVbimyPF5Bto2o0qGLizGyHYig953XtlI3yQOpfbGJCVCRKmE8rfb3tz3K5hAkTRbv i1sg== X-Gm-Message-State: ABy/qLbSsgkXWCtt7BxztwqZerL/VWbeqdb0waIq0TDqeqwnTaKi1jc7 U8cf+M2xORvJagWlDX8nUjUP6Q== X-Google-Smtp-Source: APBJJlFPWsJ9UUvyXPKGTP406O50bV7Q/6usxZuBSXPnk3Ri0enBPV1j0pOYb37plBHyyigt+Sgy8g== X-Received: by 2002:a5d:4489:0:b0:313:f38d:555f with SMTP id j9-20020a5d4489000000b00313f38d555fmr3856610wrq.24.1690029719827; Sat, 22 Jul 2023 05:41:59 -0700 (PDT) Received: from alex-rivos.ba.rivosinc.com (amontpellier-656-1-456-62.w92-145.abo.wanadoo.fr. [92.145.124.62]) by smtp.gmail.com with ESMTPSA id r6-20020adff106000000b0031424950a99sm6863986wro.81.2023.07.22.05.41.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Jul 2023 05:41:59 -0700 (PDT) From: Alexandre Ghiti To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Ard Biesheuvel , Kees Cook , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Alexandre Ghiti Subject: [PATCH v6 3/5] arm64: libstub: Move KASLR handling functions to kaslr.c Date: Sat, 22 Jul 2023 14:38:48 +0200 Message-Id: <20230722123850.634544-4-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230722123850.634544-1-alexghiti@rivosinc.com> References: <20230722123850.634544-1-alexghiti@rivosinc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org This prepares for riscv to use the same functions to handle the pĥysical kernel move when KASLR is enabled. Signed-off-by: Alexandre Ghiti Acked-by: Ard Biesheuvel --- arch/arm64/include/asm/efi.h | 2 + drivers/firmware/efi/libstub/Makefile | 2 +- drivers/firmware/efi/libstub/arm64-stub.c | 117 ++-------------- drivers/firmware/efi/libstub/efistub.h | 8 ++ drivers/firmware/efi/libstub/kaslr.c | 159 ++++++++++++++++++++++ 5 files changed, 183 insertions(+), 105 deletions(-) create mode 100644 drivers/firmware/efi/libstub/kaslr.c diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 4cf2cb053bc8..46273ee89445 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -168,4 +168,6 @@ static inline void efi_capsule_flush_cache_range(void *addr, int size) efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f); +void efi_icache_sync(unsigned long start, unsigned long end); + #endif /* _ASM_EFI_H */ diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 16d64a34d1e1..11aba8a041ec 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -86,7 +86,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \ screen_info.o efi-stub-entry.o lib-$(CONFIG_ARM) += arm32-stub.o -lib-$(CONFIG_ARM64) += arm64.o arm64-stub.o smbios.o +lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o lib-$(CONFIG_X86) += x86-stub.o lib-$(CONFIG_RISCV) += riscv.o riscv-stub.o lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index 770b8ecb7398..452b7ccd330e 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -14,42 +14,6 @@ #include "efistub.h" -/* - * Distro versions of GRUB may ignore the BSS allocation entirely (i.e., fail - * to provide space, and fail to zero it). Check for this condition by double - * checking that the first and the last byte of the image are covered by the - * same EFI memory map entry. - */ -static bool check_image_region(u64 base, u64 size) -{ - struct efi_boot_memmap *map; - efi_status_t status; - bool ret = false; - int map_offset; - - status = efi_get_memory_map(&map, false); - if (status != EFI_SUCCESS) - return false; - - for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) { - efi_memory_desc_t *md = (void *)map->map + map_offset; - u64 end = md->phys_addr + md->num_pages * EFI_PAGE_SIZE; - - /* - * Find the region that covers base, and return whether - * it covers base+size bytes. - */ - if (base >= md->phys_addr && base < end) { - ret = (base + size) <= end; - break; - } - } - - efi_bs_call(free_pool, map); - - return ret; -} - efi_status_t handle_kernel_image(unsigned long *image_addr, unsigned long *image_size, unsigned long *reserve_addr, @@ -59,31 +23,6 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, { efi_status_t status; unsigned long kernel_size, kernel_codesize, kernel_memsize; - u32 phys_seed = 0; - u64 min_kimg_align = efi_get_kimg_min_align(); - - if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { - efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID; - void *p; - - if (efi_nokaslr) { - efi_info("KASLR disabled on kernel command line\n"); - } else if (efi_bs_call(handle_protocol, image_handle, - &li_fixed_proto, &p) == EFI_SUCCESS) { - efi_info("Image placement fixed by loader\n"); - } else { - status = efi_get_random_bytes(sizeof(phys_seed), - (u8 *)&phys_seed); - if (status == EFI_NOT_FOUND) { - efi_info("EFI_RNG_PROTOCOL unavailable\n"); - efi_nokaslr = true; - } else if (status != EFI_SUCCESS) { - efi_err("efi_get_random_bytes() failed (0x%lx)\n", - status); - efi_nokaslr = true; - } - } - } if (image->image_base != _text) { efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n"); @@ -98,50 +37,15 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, kernel_codesize = __inittext_end - _text; kernel_memsize = kernel_size + (_end - _edata); *reserve_size = kernel_memsize; + *image_addr = (unsigned long)_text; - if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) { - /* - * If KASLR is enabled, and we have some randomness available, - * locate the kernel at a randomized offset in physical memory. - */ - status = efi_random_alloc(*reserve_size, min_kimg_align, - reserve_addr, phys_seed, - EFI_LOADER_CODE); - if (status != EFI_SUCCESS) - efi_warn("efi_random_alloc() failed: 0x%lx\n", status); - } else { - status = EFI_OUT_OF_RESOURCES; - } - - if (status != EFI_SUCCESS) { - if (!check_image_region((u64)_text, kernel_memsize)) { - efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n"); - } else if (IS_ALIGNED((u64)_text, min_kimg_align) && - (u64)_end < EFI_ALLOC_LIMIT) { - /* - * Just execute from wherever we were loaded by the - * UEFI PE/COFF loader if the placement is suitable. - */ - *image_addr = (u64)_text; - *reserve_size = 0; - return EFI_SUCCESS; - } - - status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, - ULONG_MAX, min_kimg_align, - EFI_LOADER_CODE); - - if (status != EFI_SUCCESS) { - efi_err("Failed to relocate kernel\n"); - *reserve_size = 0; - return status; - } - } - - *image_addr = *reserve_addr; - memcpy((void *)*image_addr, _text, kernel_size); - caches_clean_inval_pou(*image_addr, *image_addr + kernel_codesize); - efi_remap_image(*image_addr, *reserve_size, kernel_codesize); + status = efi_kaslr_relocate_kernel(image_addr, + reserve_addr, reserve_size, + kernel_size, kernel_codesize, + kernel_memsize, + efi_kaslr_get_phys_seed(image_handle)); + if (status != EFI_SUCCESS) + return status; return EFI_SUCCESS; } @@ -159,3 +63,8 @@ unsigned long primary_entry_offset(void) */ return (char *)primary_entry - _text; } + +void efi_icache_sync(unsigned long start, unsigned long end) +{ + caches_clean_inval_pou(start, end); +} diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 6aa38a1bf126..b1a1037567ba 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -1132,6 +1132,14 @@ const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record, void efi_remap_image(unsigned long image_base, unsigned alloc_size, unsigned long code_size); +efi_status_t efi_kaslr_relocate_kernel(unsigned long *image_addr, + unsigned long *reserve_addr, + unsigned long *reserve_size, + unsigned long kernel_size, + unsigned long kernel_codesize, + unsigned long kernel_memsize, + u32 phys_seed); +u32 efi_kaslr_get_phys_seed(efi_handle_t image_handle); asmlinkage efi_status_t __efiapi efi_zboot_entry(efi_handle_t handle, efi_system_table_t *systab); diff --git a/drivers/firmware/efi/libstub/kaslr.c b/drivers/firmware/efi/libstub/kaslr.c new file mode 100644 index 000000000000..be0c8ab0982a --- /dev/null +++ b/drivers/firmware/efi/libstub/kaslr.c @@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Helper functions used by the EFI stub on multiple + * architectures to deal with physical address space randomization. + */ +#include + +#include "efistub.h" + +/** + * efi_kaslr_get_phys_seed() - Get random seed for physical kernel KASLR + * @image_handle: Handle to the image + * + * If KASLR is not disabled, obtain a random seed using EFI_RNG_PROTOCOL + * that will be used to move the kernel physical mapping. + * + * Return: the random seed + */ +u32 efi_kaslr_get_phys_seed(efi_handle_t image_handle) +{ + efi_status_t status; + u32 phys_seed; + efi_guid_t li_fixed_proto = LINUX_EFI_LOADED_IMAGE_FIXED_GUID; + void *p; + + if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE)) + return 0; + + if (efi_nokaslr) { + efi_info("KASLR disabled on kernel command line\n"); + } else if (efi_bs_call(handle_protocol, image_handle, + &li_fixed_proto, &p) == EFI_SUCCESS) { + efi_info("Image placement fixed by loader\n"); + } else { + status = efi_get_random_bytes(sizeof(phys_seed), + (u8 *)&phys_seed); + if (status == EFI_SUCCESS) { + return phys_seed; + } else if (status == EFI_NOT_FOUND) { + efi_info("EFI_RNG_PROTOCOL unavailable\n"); + efi_nokaslr = true; + } else if (status != EFI_SUCCESS) { + efi_err("efi_get_random_bytes() failed (0x%lx)\n", + status); + efi_nokaslr = true; + } + } + + return 0; +} + +/* + * Distro versions of GRUB may ignore the BSS allocation entirely (i.e., fail + * to provide space, and fail to zero it). Check for this condition by double + * checking that the first and the last byte of the image are covered by the + * same EFI memory map entry. + */ +static bool check_image_region(u64 base, u64 size) +{ + struct efi_boot_memmap *map; + efi_status_t status; + bool ret = false; + int map_offset; + + status = efi_get_memory_map(&map, false); + if (status != EFI_SUCCESS) + return false; + + for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) { + efi_memory_desc_t *md = (void *)map->map + map_offset; + u64 end = md->phys_addr + md->num_pages * EFI_PAGE_SIZE; + + /* + * Find the region that covers base, and return whether + * it covers base+size bytes. + */ + if (base >= md->phys_addr && base < end) { + ret = (base + size) <= end; + break; + } + } + + efi_bs_call(free_pool, map); + + return ret; +} + +/** + * efi_kaslr_relocate_kernel() - Relocate the kernel (random if KASLR enabled) + * @image_addr: Pointer to the current kernel location + * @reserve_addr: Pointer to the relocated kernel location + * @reserve_size: Size of the relocated kernel + * @kernel_size: Size of the text + data + * @kernel_codesize: Size of the text + * @kernel_memsize: Size of the text + data + bss + * @phys_seed: Random seed used for the relocation + * + * If KASLR is not enabled, this function relocates the kernel to a fixed + * address (or leave it as its current location). If KASLR is enabled, the + * kernel physical location is randomized using the seed in parameter. + * + * Return: status code, EFI_SUCCESS if relocation is successful + */ +efi_status_t efi_kaslr_relocate_kernel(unsigned long *image_addr, + unsigned long *reserve_addr, + unsigned long *reserve_size, + unsigned long kernel_size, + unsigned long kernel_codesize, + unsigned long kernel_memsize, + u32 phys_seed) +{ + efi_status_t status; + u64 min_kimg_align = efi_get_kimg_min_align(); + + if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) { + /* + * If KASLR is enabled, and we have some randomness available, + * locate the kernel at a randomized offset in physical memory. + */ + status = efi_random_alloc(*reserve_size, min_kimg_align, + reserve_addr, phys_seed, + EFI_LOADER_CODE); + if (status != EFI_SUCCESS) + efi_warn("efi_random_alloc() failed: 0x%lx\n", status); + } else { + status = EFI_OUT_OF_RESOURCES; + } + + if (status != EFI_SUCCESS) { + if (!check_image_region(*image_addr, kernel_memsize)) { + efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n"); + } else if (IS_ALIGNED(*image_addr, min_kimg_align) && + (u64)_end < EFI_ALLOC_LIMIT) { + /* + * Just execute from wherever we were loaded by the + * UEFI PE/COFF loader if the placement is suitable. + */ + *reserve_size = 0; + return EFI_SUCCESS; + } + + status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, + ULONG_MAX, min_kimg_align, + EFI_LOADER_CODE); + + if (status != EFI_SUCCESS) { + efi_err("Failed to relocate kernel\n"); + *reserve_size = 0; + return status; + } + } + + memcpy((void *)*reserve_addr, (void *)*image_addr, kernel_size); + *image_addr = *reserve_addr; + efi_icache_sync(*image_addr, *image_addr + kernel_codesize); + efi_remap_image(*image_addr, *reserve_size, kernel_codesize); + + return status; +} From patchwork Sat Jul 22 12:38:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Ghiti X-Patchwork-Id: 705674 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 9D158EB64DA for ; Sat, 22 Jul 2023 12:43:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229597AbjGVMnE (ORCPT ); Sat, 22 Jul 2023 08:43:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51608 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230454AbjGVMnE (ORCPT ); Sat, 22 Jul 2023 08:43:04 -0400 Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B16710F5 for ; Sat, 22 Jul 2023 05:43:02 -0700 (PDT) Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-3141fa31c2bso2052436f8f.2 for ; Sat, 22 Jul 2023 05:43:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20221208.gappssmtp.com; s=20221208; t=1690029781; x=1690634581; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/der0KJlDJ6cwsQs4A7+tIRkxDY3MMfqGccPHIlX2cU=; b=gLMFot1BkI0ANTW5TAy3Bb9fjvPkiUYnwOGIenuWohOLcknH0XGZ0PpcM+5zX60Z+m 6O4mMv39vxTp/o926alCtUzZc0ivcxXTWHFsLiwv6C4Q2uWPZiqQqH7ZRG7cAyIIDqdy Susq5+QUDRzIxDTk4TkHnxVhYEgD48ErFCEHctoPsAin4wdcl/dH0Zc/OtXYWM33syru Y7w3nuCizPPyraqKoDNUV/m3+Rheyc7jQn3KCBJ8/ZvNAsHAxzPaOmiORG74HLe+FOg4 lU9ZgkmtlURKG7U2HY6d77tMENB8qrjtfCa9/CDqOzOTj7KREym6sTWEMenKl303dxM2 TM1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690029781; x=1690634581; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/der0KJlDJ6cwsQs4A7+tIRkxDY3MMfqGccPHIlX2cU=; b=lNPMVGZAmbB9rN/txPMAMNZfFbjg8hyBXp/vLidGtI4KIN7j/F5AIPO1fs2rEZnLRJ xliXUsi9bARml6rA+E4eJKzTojch3Zt+X5ujDL6Z1bnNNPhsK9rGn2702V1s7PofnvRG pZ3fL2FDwGVKwLi/tk0sJYLuOrN2NpVfHXxUoXlT5MZjmLQf44XXXz2zBWdAWobysahc DWAzKF1iSmMYcQO3AwpzKobRJL6wDYxhJom9soPjWDphN9Q+7VVdSTnEBX07oE4SrNsw DmFnnkZg4axYkYfhCiF9wjphQokCUVj9tpTMlRPk8hSGakc+kJ74wc3WGRycP8Q+d7fz vh+g== X-Gm-Message-State: ABy/qLaqynfcLqN6vyl3ZM01D//Wy7ctwQpbVGvsDR7W6OarWRoIVAac X6oHBOGf3cjMnhemW8DQC5hEGQ== X-Google-Smtp-Source: APBJJlHkvTt0JkOjTHC/10qCFsIyDPIAfKz5RSmvzPMUq5Ej1dnP9W1WU/kGxqayUnfN2+92c6cZ+Q== X-Received: by 2002:adf:e6d0:0:b0:313:fff0:ff44 with SMTP id y16-20020adfe6d0000000b00313fff0ff44mr3603578wrm.38.1690029780939; Sat, 22 Jul 2023 05:43:00 -0700 (PDT) Received: from alex-rivos.ba.rivosinc.com (amontpellier-656-1-456-62.w92-145.abo.wanadoo.fr. [92.145.124.62]) by smtp.gmail.com with ESMTPSA id t10-20020a5d690a000000b00316fc844be7sm6834681wru.36.2023.07.22.05.43.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Jul 2023 05:43:00 -0700 (PDT) From: Alexandre Ghiti To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Ard Biesheuvel , Kees Cook , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Alexandre Ghiti Subject: [PATCH v6 4/5] libstub: Fix compilation warning for rv32 Date: Sat, 22 Jul 2023 14:38:49 +0200 Message-Id: <20230722123850.634544-5-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230722123850.634544-1-alexghiti@rivosinc.com> References: <20230722123850.634544-1-alexghiti@rivosinc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Fix the following warning which appears when compiled for rv32 by using unsigned long type instead of u64. ../drivers/firmware/efi/libstub/efi-stub-helper.c: In function 'efi_kaslr_relocate_kernel': ../drivers/firmware/efi/libstub/efi-stub-helper.c:846:28: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 846 | (u64)_end < EFI_ALLOC_LIMIT) { Signed-off-by: Alexandre Ghiti Acked-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/kaslr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/efi/libstub/kaslr.c b/drivers/firmware/efi/libstub/kaslr.c index be0c8ab0982a..afb857329799 100644 --- a/drivers/firmware/efi/libstub/kaslr.c +++ b/drivers/firmware/efi/libstub/kaslr.c @@ -130,7 +130,7 @@ efi_status_t efi_kaslr_relocate_kernel(unsigned long *image_addr, if (!check_image_region(*image_addr, kernel_memsize)) { efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n"); } else if (IS_ALIGNED(*image_addr, min_kimg_align) && - (u64)_end < EFI_ALLOC_LIMIT) { + (unsigned long)_end < EFI_ALLOC_LIMIT) { /* * Just execute from wherever we were loaded by the * UEFI PE/COFF loader if the placement is suitable. From patchwork Sat Jul 22 12:38:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Ghiti X-Patchwork-Id: 705492 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 65206EB64DA for ; Sat, 22 Jul 2023 12:44:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229699AbjGVMoF (ORCPT ); Sat, 22 Jul 2023 08:44:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52094 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229903AbjGVMoF (ORCPT ); Sat, 22 Jul 2023 08:44:05 -0400 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [IPv6:2a00:1450:4864:20::32f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80C962686 for ; Sat, 22 Jul 2023 05:44:03 -0700 (PDT) Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-3fc0aecf107so22366995e9.2 for ; Sat, 22 Jul 2023 05:44:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20221208.gappssmtp.com; s=20221208; t=1690029842; x=1690634642; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YeCObNb4PmolJTFe26id2IecwNBs81NuN62SQUhE5h0=; b=pUM+520vb2S92A6ynS7MBf+a+TvlSycieG6x/eLAxB9vkNf2NAAk3hKz2lVbEhN6Km 9D+OpTxN358e0ePT4GlQNjD4y8JMqJED6JHYZ1vhglRCGL+/9vv8wgBa/4HC0Fg3s8wl rq+o2tb+8mmawwLyIZAoIgVi0mtbElZCDvcWyHCsAUhpD8yih7TyKqRWkFD9vcKvJ5l5 To5s+Yl8KRng8QyCvHUYBfFXpVY39ST6SArgtFX6PcsvC0376cKqK/E6lDNOuZdou2k4 ZmWsNfaeoEOrbmUCy2hQGQ6pkeaaasNFlU+Xmn7w+FgnOZcFNhGwUveLYe1tubOKHwSl xSJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690029842; x=1690634642; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YeCObNb4PmolJTFe26id2IecwNBs81NuN62SQUhE5h0=; b=C6AmRh6KJ5Ewe+oOv6/GaD/zorNQvHQ/bagG2t2Ot0V2IBZt+OKYxQVaItnWNhyYUF 97/EBZ2IV4CvTsOTWhwc0qYfJl9b8niy/BgBlz2qAuiORh3nnsLorn/ZwsmFXzspKzCQ DER0xeHdUz4Qjc7m5pdzsMhG7XopRDaz82et7bm+evX9cvg24TpDSi2N7IYcMHBPbApM OdAYL+1C8um5Kt2AxlX4YWRTad3eqP5Yc5D5tAOrbyAQkjzTNwI75/HmRtCrSeid2ud1 pSvA8hhkjmhgliun2fisodZ5t+J/EO37iI+7XIrcSctDvKuEHjArkHgWuK3y6KnGz9+1 Whpg== X-Gm-Message-State: ABy/qLabJKaQcL0FrRODo+/XB5kCYl1oBwpYj2pL0CYJlMSmkeKdeP9Q YlzPfVQRGDucEzKraucratg5gg== X-Google-Smtp-Source: APBJJlESOn48Uam2uBAko67ZqktvYU2AYN1QmwgL/HAND5SbQf6wVpva7H1fOV9++dlkWv6Q6TZ77g== X-Received: by 2002:a05:600c:21cf:b0:3fc:e00:5275 with SMTP id x15-20020a05600c21cf00b003fc0e005275mr2809721wmj.2.1690029841797; Sat, 22 Jul 2023 05:44:01 -0700 (PDT) Received: from alex-rivos.ba.rivosinc.com (amontpellier-656-1-456-62.w92-145.abo.wanadoo.fr. [92.145.124.62]) by smtp.gmail.com with ESMTPSA id n11-20020a7bcbcb000000b003fba92fad35sm7985875wmi.26.2023.07.22.05.44.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 22 Jul 2023 05:44:01 -0700 (PDT) From: Alexandre Ghiti To: Paul Walmsley , Palmer Dabbelt , Albert Ou , Ard Biesheuvel , Kees Cook , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: Alexandre Ghiti Subject: [PATCH v6 5/5] riscv: libstub: Implement KASLR by using generic functions Date: Sat, 22 Jul 2023 14:38:50 +0200 Message-Id: <20230722123850.634544-6-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230722123850.634544-1-alexghiti@rivosinc.com> References: <20230722123850.634544-1-alexghiti@rivosinc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org We can now use arm64 functions to handle the move of the kernel physical mapping: if KASLR is enabled, we will try to get a random seed from the firmware, if not possible, the kernel will be moved to a location that suits its alignment constraints. Signed-off-by: Alexandre Ghiti --- arch/riscv/include/asm/efi.h | 2 ++ arch/riscv/kernel/image-vars.h | 1 + drivers/firmware/efi/libstub/Makefile | 2 +- drivers/firmware/efi/libstub/riscv-stub.c | 33 +++++++++++------------ 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h index 29e9a0d84b16..00b24ba55035 100644 --- a/arch/riscv/include/asm/efi.h +++ b/arch/riscv/include/asm/efi.h @@ -51,4 +51,6 @@ void efi_virtmap_unload(void); unsigned long stext_offset(void); +void efi_icache_sync(unsigned long start, unsigned long end); + #endif /* _ASM_EFI_H */ diff --git a/arch/riscv/kernel/image-vars.h b/arch/riscv/kernel/image-vars.h index 15616155008c..ea1a10355ce9 100644 --- a/arch/riscv/kernel/image-vars.h +++ b/arch/riscv/kernel/image-vars.h @@ -27,6 +27,7 @@ __efistub__start = _start; __efistub__start_kernel = _start_kernel; __efistub__end = _end; __efistub__edata = _edata; +__efistub___init_text_end = __init_text_end; __efistub_screen_info = screen_info; #endif diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 11aba8a041ec..dc90a31b189f 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -88,7 +88,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \ lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o lib-$(CONFIG_X86) += x86-stub.o -lib-$(CONFIG_RISCV) += riscv.o riscv-stub.o +lib-$(CONFIG_RISCV) += kaslr.o riscv.o riscv-stub.o lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) diff --git a/drivers/firmware/efi/libstub/riscv-stub.c b/drivers/firmware/efi/libstub/riscv-stub.c index 145c9f0ba217..c96d6dcee86c 100644 --- a/drivers/firmware/efi/libstub/riscv-stub.c +++ b/drivers/firmware/efi/libstub/riscv-stub.c @@ -30,32 +30,29 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, efi_loaded_image_t *image, efi_handle_t image_handle) { - unsigned long kernel_size = 0; - unsigned long preferred_addr; + unsigned long kernel_size, kernel_codesize, kernel_memsize; efi_status_t status; kernel_size = _edata - _start; + kernel_codesize = __init_text_end - _start; + kernel_memsize = kernel_size + (_end - _edata); *image_addr = (unsigned long)_start; - *image_size = kernel_size + (_end - _edata); - - /* - * RISC-V kernel maps PAGE_OFFSET virtual address to the same physical - * address where kernel is booted. That's why kernel should boot from - * as low as possible to avoid wastage of memory. Currently, dram_base - * is occupied by the firmware. So the preferred address for kernel to - * boot is next aligned address. If preferred address is not available, - * relocate_kernel will fall back to efi_low_alloc_above to allocate - * lowest possible memory region as long as the address and size meets - * the alignment constraints. - */ - preferred_addr = EFI_KIMG_PREFERRED_ADDRESS; - status = efi_relocate_kernel(image_addr, kernel_size, *image_size, - preferred_addr, efi_get_kimg_min_align(), - 0x0); + *image_size = kernel_memsize; + *reserve_size = *image_size; + status = efi_kaslr_relocate_kernel(image_addr, + reserve_addr, reserve_size, + kernel_size, kernel_codesize, kernel_memsize, + efi_kaslr_get_phys_seed(image_handle)); if (status != EFI_SUCCESS) { efi_err("Failed to relocate kernel\n"); *image_size = 0; } + return status; } + +void efi_icache_sync(unsigned long start, unsigned long end) +{ + asm volatile ("fence.i" ::: "memory"); +}