From patchwork Mon Feb 6 12:49:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 651143 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 F3712C636D6 for ; Mon, 6 Feb 2023 12:49:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229640AbjBFMtw (ORCPT ); Mon, 6 Feb 2023 07:49:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229976AbjBFMtv (ORCPT ); Mon, 6 Feb 2023 07:49:51 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A34B614223 for ; Mon, 6 Feb 2023 04:49:50 -0800 (PST) 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 2B02360EB8 for ; Mon, 6 Feb 2023 12:49:50 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3AF05C433A4; Mon, 6 Feb 2023 12:49:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1675687789; bh=EXNH/fSwpA4HsBvvS096eTWjFLTtoETYbymTTVg2QLU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r8UUMvGzluvZRa23V9J1wIr32NVVFKYAGrzQR5mMboNkaOAet26xM4Do+nqQ6KRTH D8CfP7efO25kv3Nli/f1Fxy8UOJh4X0DNS8WH12sPtQEPOoLeFivoam1GnCBhvuvyp Ft9AP2ibQcwaXq8t88mnqMhixMyVNEyI+zL2UasmdJGJatuff0rOiIyfqFaR9OCb/q IjdG8LKCnysQfds5F/dqOFOAkjPk0uC8KRoFifO2n/OlcWIIUyerAozBgcb7f6DXGz VU9i6nWWYskkDhy6gnoqrE+HIJtNnfwOuU3zuttQ5LXt8WgKK+b2TuGlbwMmdAjNjg VHgmqVzEoSw8Q== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Catalin Marinas , Will Deacon , Kees Cook , Mark Rutland , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen Subject: [PATCH v2 1/3] efi: Discover BTI support in runtime services regions Date: Mon, 6 Feb 2023 13:49:36 +0100 Message-Id: <20230206124938.272988-2-ardb@kernel.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230206124938.272988-1-ardb@kernel.org> References: <20230206124938.272988-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7231; i=ardb@kernel.org; h=from:subject; bh=EXNH/fSwpA4HsBvvS096eTWjFLTtoETYbymTTVg2QLU=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBj4PdeY3MXGNqiWpNQ/c8m4MRoWCtxj+e2MZ3Yv 0AcQ5NEywmJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY+D3XgAKCRDDTyI5ktmP JEE9C/9oH6i96Jd30ffYj9DQEDrLoXGoA/0g7cvdVbN1nRRit5G2f7Rgam61Kq7IES2TDKG3GCV 92AuOwx0m4nVZHg5bfCsyOpOKHFmCeWCHn8qqdDovi/YacgMvit8VU69PqxJ1b9T8o7IN3+A2hs dYKEkApdfwafYoJqIEtW12BL7IR0KcAHIduUCq1+qlZigAGk39lWWI0myJNjtjBIgWmNAXU9HR/ vDWZxLHvmDg/c00RAHN6IlVt3iAvoT7s/4ibmv/lKE3EN+cZzZVtxsiyByTeJSyh1vlMEgybV8P y9Sle+TYkcY6vkAalplPruoSJbqMStKYEOjuUazQpXHCn+Sm3DngUvXprAApA6jaHKtLgQPBq+f 8jER0BA4nqO/TuO9lA7MTDhKnyhWtxhzEAxMzWWtmuiYaLYy0Qx+9m2mVsq3hClZm2JTt+vMPhg antNBVqwuTM4DL6d8EG8KVcgixg7YYaHV4ozOi4JbFAeKKOjey4Flab3w2uDdGBZFNfiE= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Add the generic plumbing to detect whether or not the runtime code regions were constructed with BTI/IBT landing pads by the firmware, permitting the OS to enable enforcement when mapping these regions into the OS's address space. Signed-off-by: Ard Biesheuvel Reviewed-by: Kees Cook --- arch/arm/include/asm/efi.h | 2 +- arch/arm/kernel/efi.c | 5 +++-- arch/arm64/include/asm/efi.h | 3 ++- arch/arm64/kernel/efi.c | 3 ++- arch/riscv/include/asm/efi.h | 2 +- arch/riscv/kernel/efi.c | 3 ++- arch/x86/platform/efi/efi_64.c | 3 ++- drivers/firmware/efi/memattr.c | 7 ++++++- include/linux/efi.h | 8 ++++++-- 9 files changed, 25 insertions(+), 11 deletions(-) diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index b95241b1ca656f3c..78282ced50387dd3 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -20,7 +20,7 @@ void efi_init(void); void arm_efi_init(void); int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); -int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); +int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool); #define arch_efi_call_virt_setup() efi_virtmap_load() #define arch_efi_call_virt_teardown() efi_virtmap_unload() diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index 882104f43b3b0928..e2b9d2618c6727c6 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c @@ -23,7 +23,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data) } int __init efi_set_mapping_permissions(struct mm_struct *mm, - efi_memory_desc_t *md) + efi_memory_desc_t *md, + bool ignored) { unsigned long base, size; @@ -71,7 +72,7 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) * If stricter permissions were specified, apply them now. */ if (md->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP)) - return efi_set_mapping_permissions(mm, md); + return efi_set_mapping_permissions(mm, md, false); return 0; } diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 31d13a6001df49c4..5d47d429672b1bfb 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -27,7 +27,8 @@ bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg) #endif int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); -int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); +int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, + bool has_bti); #define arch_efi_call_virt_setup() \ ({ \ diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index fab05de2e12dd5d8..78ffd5aaddcbbaee 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -110,7 +110,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data) } int __init efi_set_mapping_permissions(struct mm_struct *mm, - efi_memory_desc_t *md) + efi_memory_desc_t *md, + bool has_bti) { BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && md->type != EFI_RUNTIME_SERVICES_DATA); diff --git a/arch/riscv/include/asm/efi.h b/arch/riscv/include/asm/efi.h index 47d3ab0fcc36a186..29e9a0d84b16682f 100644 --- a/arch/riscv/include/asm/efi.h +++ b/arch/riscv/include/asm/efi.h @@ -19,7 +19,7 @@ extern void efi_init(void); #endif int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); -int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); +int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool); #define arch_efi_call_virt_setup() ({ \ sync_kernel_mappings(efi_mm.pgd); \ diff --git a/arch/riscv/kernel/efi.c b/arch/riscv/kernel/efi.c index 1aa540350abd31b0..aa6209a74c83ffc2 100644 --- a/arch/riscv/kernel/efi.c +++ b/arch/riscv/kernel/efi.c @@ -78,7 +78,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data) } int __init efi_set_mapping_permissions(struct mm_struct *mm, - efi_memory_desc_t *md) + efi_memory_desc_t *md, + bool ignored) { BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && md->type != EFI_RUNTIME_SERVICES_DATA); diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index b36596bf0fc38f4f..2e6fe430cb07bbbc 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -389,7 +389,8 @@ static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf) return err1 || err2; } -static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md) +static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md, + bool has_ibt) { unsigned long pf = 0; diff --git a/drivers/firmware/efi/memattr.c b/drivers/firmware/efi/memattr.c index 0a9aba5f9ceff0bf..3cbf00f04c5b60ca 100644 --- a/drivers/firmware/efi/memattr.c +++ b/drivers/firmware/efi/memattr.c @@ -129,6 +129,7 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm, efi_memattr_perm_setter fn) { efi_memory_attributes_table_t *tbl; + bool has_bti = false; int i, ret; if (tbl_size <= sizeof(*tbl)) @@ -150,6 +151,10 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm, return -ENOMEM; } + if (tbl->version > 1 && + (tbl->flags & EFI_MEMORY_ATTRIBUTES_FLAGS_RT_FORWARD_CONTROL_FLOW_GUARD)) + has_bti = true; + if (efi_enabled(EFI_DBG)) pr_info("Processing EFI Memory Attributes table:\n"); @@ -169,7 +174,7 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm, efi_md_typeattr_format(buf, sizeof(buf), &md)); if (valid) { - ret = fn(mm, &md); + ret = fn(mm, &md, has_bti); if (ret) pr_err("Error updating mappings, skipping subsequent md's\n"); } diff --git a/include/linux/efi.h b/include/linux/efi.h index 9d455d502ac92b65..df88786b59471714 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -584,11 +584,15 @@ typedef struct { #define EFI_INVALID_TABLE_ADDR (~0UL) +// BIT0 implies that Runtime code includes the forward control flow guard +// instruction, such as X86 CET-IBT or ARM BTI. +#define EFI_MEMORY_ATTRIBUTES_FLAGS_RT_FORWARD_CONTROL_FLOW_GUARD 0x1 + typedef struct { u32 version; u32 num_entries; u32 desc_size; - u32 reserved; + u32 flags; efi_memory_desc_t entry[0]; } efi_memory_attributes_table_t; @@ -751,7 +755,7 @@ extern unsigned long efi_mem_attr_table; * argument in the page tables referred to by the * first argument. */ -typedef int (*efi_memattr_perm_setter)(struct mm_struct *, efi_memory_desc_t *); +typedef int (*efi_memattr_perm_setter)(struct mm_struct *, efi_memory_desc_t *, bool); extern int efi_memattr_init(void); extern int efi_memattr_apply_permissions(struct mm_struct *mm, From patchwork Mon Feb 6 12:49:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 652170 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 9FAD7C05027 for ; Mon, 6 Feb 2023 12:49:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229528AbjBFMt5 (ORCPT ); Mon, 6 Feb 2023 07:49:57 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229656AbjBFMt4 (ORCPT ); Mon, 6 Feb 2023 07:49:56 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0205611161 for ; Mon, 6 Feb 2023 04:49:55 -0800 (PST) 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 ABA68B81011 for ; Mon, 6 Feb 2023 12:49:53 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0AAE7C4339B; Mon, 6 Feb 2023 12:49:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1675687792; bh=IAL+pyfoXhXmgoxqxIVL+RHhIgd+a/xg78zxfOh6js8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KHgObYG1983YEkn2WpX9MLJNsVgoBr1huXTcgOb60NyNNZPeagzOi+fToiYBobdf5 QB0U9VOdFZ7kzP9uzUkbgwnwbr5lV7Z9wADlMrPtS+SxI5oryykriXACt1y/r7P3XR MqiwRd4YHxcLWlchfagdlgqKxbtCvbkN1RIl1t0EwYKjeVjD+ReY08w7sgpDDqLg4c AXExiANxIVV1sC/VVIACWbilcdrsallfgqxw53yh3nn0lWlnHGi40KK3T2YupUxQyV eXVr9fyAMzK3VcV+v14qVk9kpxlExFmU7Qobl0Q+esjmZGgdt0vhKr+rgRVMpJpIN3 N1rT5/QFAWz+A== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Catalin Marinas , Will Deacon , Kees Cook , Mark Rutland , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen Subject: [PATCH v2 2/3] efi: arm64: Wire up BTI annotation in memory attributes table Date: Mon, 6 Feb 2023 13:49:37 +0100 Message-Id: <20230206124938.272988-3-ardb@kernel.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230206124938.272988-1-ardb@kernel.org> References: <20230206124938.272988-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2919; i=ardb@kernel.org; h=from:subject; bh=IAL+pyfoXhXmgoxqxIVL+RHhIgd+a/xg78zxfOh6js8=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBj4PdgBcM69q4ZgV9oBMnKOIQvX9UQ3M+1JdiBQ BJDjWLmv5WJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY+D3YAAKCRDDTyI5ktmP JEKAC/wLQYTaKY56agma250TeBbtIzcObQl0Lz5neU2J38P/NY9AQ/dMKjxx29L44HQdBRT5hpJ inmju3b/pFpSxXE1AwEUcGOpkOq5Jdgfq+CWuMPZUqh2XGQyht8HgqliKgs76vVqyoCFpBUmMq5 KmZi5H0pOaAT8beaTCXTaXEBKHVMVhtKHH2Z/30YPBHfr/lJl5ViF1xKkRNh5tG9iCd3HSis8Rw ohFwcLSZS2wHB71j4CMQlHabse+6z3Q5R86uHQ+vETM+XYN8+bSbEqGxDqvMzNx+8HvUAmZIkZx 3og5mQDIvz6eXxx772p6+Mc/KZx6kY2cbqwyp8eXI5UfJOirebyyib51va3vlrVaWqlA6k/+Vmr IQs3UyzmYDPP0b3vkBPyb0eUStPjbemQtE0wjXx452uN7NM06zj5c/9F7zuzCuC4u8f3bgK9FBw R5pie/mKThyv6dN6kc60HJ8T0t0SU7G8YZWKbv27Ell5xczOICcmjqJmRyLm569rfwYNc= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org UEFI v2.10 extends the EFI memory attributes table with a flag that indicates whether or not all RuntimeServicesCode regions were constructed with BTI landing pads, permitting the OS to map these regions with BTI restrictions enabled. So let's take this into account on arm64. Signed-off-by: Ard Biesheuvel Reviewed-by: Kees Cook Acked-by: Mark Rutland Reviewed-by: Will Deacon --- arch/arm64/kernel/efi.c | 14 ++++++++++++-- arch/arm64/kernel/traps.c | 6 ++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 78ffd5aaddcbbaee..99971cd349f36310 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -96,15 +96,23 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) return 0; } +struct set_perm_data { + const efi_memory_desc_t *md; + bool has_bti; +}; + static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data) { - efi_memory_desc_t *md = data; + struct set_perm_data *spd = data; + const efi_memory_desc_t *md = spd->md; pte_t pte = READ_ONCE(*ptep); if (md->attribute & EFI_MEMORY_RO) pte = set_pte_bit(pte, __pgprot(PTE_RDONLY)); if (md->attribute & EFI_MEMORY_XP) pte = set_pte_bit(pte, __pgprot(PTE_PXN)); + else if (system_supports_bti() && spd->has_bti) + pte = set_pte_bit(pte, __pgprot(PTE_GP)); set_pte(ptep, pte); return 0; } @@ -113,6 +121,8 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool has_bti) { + struct set_perm_data data = { md, has_bti }; + BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE && md->type != EFI_RUNTIME_SERVICES_DATA); @@ -128,7 +138,7 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm, */ return apply_to_page_range(mm, md->virt_addr, md->num_pages << EFI_PAGE_SHIFT, - set_permissions, md); + set_permissions, &data); } /* diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 4c0caa589e12de2a..1f366b94ea8e233a 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -492,6 +494,10 @@ void do_el0_bti(struct pt_regs *regs) void do_el1_bti(struct pt_regs *regs, unsigned long esr) { + if (efi_runtime_fixup_exception(regs, "BTI violation")) { + regs->pstate &= ~PSR_BTYPE_MASK; + return; + } die("Oops - BTI", regs, esr); } From patchwork Mon Feb 6 12:49:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 651142 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 440CEC61DA4 for ; Mon, 6 Feb 2023 12:50:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229656AbjBFMt7 (ORCPT ); Mon, 6 Feb 2023 07:49:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38158 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229867AbjBFMt6 (ORCPT ); Mon, 6 Feb 2023 07:49:58 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3543B1114F for ; Mon, 6 Feb 2023 04:49:56 -0800 (PST) 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 BC3AE60EC8 for ; Mon, 6 Feb 2023 12:49:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CBA93C433D2; Mon, 6 Feb 2023 12:49:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1675687795; bh=ypWkLVzNr8Pt3z1+YR2rB/b3lXmmDLV8gRNYhHND/+o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=alfOiNDKwAXNsakfgOeYLLtyjcwJwmDp9BGPONtdAJM1aLl4LcNoxAI9d3tl02p5p h05uZeCJReoMDVatWkVqHXAYnpOvqqQp3T+GVms+/R3fkbCvUa/XRuYu2dpE0qn3kA 9bKMgjDfw5mHr4EkmrPyrF9NthsBiVuog1S3SIhV0qO0TXIMuSMP9vXdDPENsf2hDO UEgsL3Jlz8jyfXKduASizMDMlHebaCfH9NtWTbe4b3YTapUaD/T37oQP75DDsfLn72 usk1VKBhfCCYprfgzsQNM3EId8tV7tnVaHjKEBUZWaUIXx26FYkvle4FLESBmHtQu9 6a+m7ArcS+V+A== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, Ard Biesheuvel , Catalin Marinas , Will Deacon , Kees Cook , Mark Rutland , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen Subject: [PATCH v2 3/3] efi: x86: Wire up IBT annotation in memory attributes table Date: Mon, 6 Feb 2023 13:49:38 +0100 Message-Id: <20230206124938.272988-4-ardb@kernel.org> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230206124938.272988-1-ardb@kernel.org> References: <20230206124938.272988-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=4596; i=ardb@kernel.org; h=from:subject; bh=ypWkLVzNr8Pt3z1+YR2rB/b3lXmmDLV8gRNYhHND/+o=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBj4PdhVcTfOpIVV8X2vNSNsb13vySymXSVFSYcv QyOqWci2hWJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY+D3YQAKCRDDTyI5ktmP JILPC/9qBm9Q868geNW3M21t+QA+Nefqh3mUkRi/GGVKHKnRe/u+ztAF7NuHYGseaoCzhrfbXl3 yF7wgScExa8nrygYNyBuSLEg9nwhBOtLdqj+18br9bW0J/1H5D430FzUGV0vUNsXnMFN9CvhfCV kh1JpIA4Abco9WFJhG6D8AtYr8qtQqiDvDuID4S2wd0ur83ZqG5jjoTiM71QgsfhnbL6CS42zuV eng+uo1GqyWYVT8teKWEDLzEpaDlqCbVl7cVMXxf0gaT9FHffPDr6dFVDPiA83FJnxakQPB1t0S WW1qzxlUsSG+rpMfSo3e1E1s6Byuc3mwPcZKzq1KPo/VaFUjRC69dWVb2fkDaQoSF/K3bT57EMo ThEUC4rz7svj/+PXURpGZ4LJUEcfFvB28L8zV3KgVNgWHZUehqMg1nzh3jzyNaS4X1ueFzChOFv 6RU+HI/TxSEuJjue7TDoad8mgERffLIMb2OFFWQebL/TT1wZ7SZARLQkRZ5Tn/eouYj7U= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org UEFI v2.10 extends the EFI memory attributes table with a flag that indicates whether or not all RuntimeServicesCode regions were constructed with ENDBR landing pads, permitting the OS to map these regions with IBT restrictions enabled. So let's take this into account on x86 as well. Suggested-by: Peter Zijlstra # ibt_save() changes Signed-off-by: Ard Biesheuvel Acked-by: Dave Hansen Acked-by: Peter Zijlstra (Intel) --- arch/x86/include/asm/efi.h | 4 +++- arch/x86/include/asm/ibt.h | 4 ++-- arch/x86/kernel/apm_32.c | 4 ++-- arch/x86/kernel/cpu/common.c | 5 +++-- arch/x86/platform/efi/efi_64.c | 5 +++++ 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index cd19b9eca3f63cbd..9f8ded3de0381973 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -106,6 +106,8 @@ static inline void efi_fpu_end(void) extern asmlinkage u64 __efi_call(void *fp, ...); +extern bool efi_disable_ibt_for_runtime; + #define efi_call(...) ({ \ __efi_nargs_check(efi_call, 7, __VA_ARGS__); \ __efi_call(__VA_ARGS__); \ @@ -121,7 +123,7 @@ extern asmlinkage u64 __efi_call(void *fp, ...); #undef arch_efi_call_virt #define arch_efi_call_virt(p, f, args...) ({ \ - u64 ret, ibt = ibt_save(); \ + u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ ret = efi_call((void *)p->f, args); \ ibt_restore(ibt); \ ret; \ diff --git a/arch/x86/include/asm/ibt.h b/arch/x86/include/asm/ibt.h index 9b08082a5d9f564b..ab427fdab4115357 100644 --- a/arch/x86/include/asm/ibt.h +++ b/arch/x86/include/asm/ibt.h @@ -74,7 +74,7 @@ static inline bool is_endbr(u32 val) return val == gen_endbr(); } -extern __noendbr u64 ibt_save(void); +extern __noendbr u64 ibt_save(bool); extern __noendbr void ibt_restore(u64 save); #else /* __ASSEMBLY__ */ @@ -100,7 +100,7 @@ extern __noendbr void ibt_restore(u64 save); static inline bool is_endbr(u32 val) { return false; } -static inline u64 ibt_save(void) { return 0; } +static inline u64 ibt_save(bool) { return 0; } static inline void ibt_restore(u64 save) { } #else /* __ASSEMBLY__ */ diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 60e330cdbd175648..c6c15ce1952fb62e 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -609,7 +609,7 @@ static long __apm_bios_call(void *_call) apm_irq_save(flags); firmware_restrict_branch_speculation_start(); - ibt = ibt_save(); + ibt = ibt_save(true); APM_DO_SAVE_SEGS; apm_bios_call_asm(call->func, call->ebx, call->ecx, &call->eax, &call->ebx, &call->ecx, &call->edx, @@ -690,7 +690,7 @@ static long __apm_bios_call_simple(void *_call) apm_irq_save(flags); firmware_restrict_branch_speculation_start(); - ibt = ibt_save(); + ibt = ibt_save(true); APM_DO_SAVE_SEGS; error = apm_bios_call_simple_asm(call->func, call->ebx, call->ecx, &call->eax); diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 9cfca3d7d0e207c5..54b246414eebb7b9 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -571,13 +571,14 @@ __setup("nopku", setup_disable_pku); #ifdef CONFIG_X86_KERNEL_IBT -__noendbr u64 ibt_save(void) +__noendbr u64 ibt_save(bool disable) { u64 msr = 0; if (cpu_feature_enabled(X86_FEATURE_IBT)) { rdmsrl(MSR_IA32_S_CET, msr); - wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN); + if (disable) + wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN); } return msr; diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 2e6fe430cb07bbbc..232acf418cfbe625 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -389,11 +389,15 @@ static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf) return err1 || err2; } +bool efi_disable_ibt_for_runtime __ro_after_init = true; + static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md, bool has_ibt) { unsigned long pf = 0; + efi_disable_ibt_for_runtime |= !has_ibt; + if (md->attribute & EFI_MEMORY_XP) pf |= _PAGE_NX; @@ -415,6 +419,7 @@ void __init efi_runtime_update_mappings(void) * exists, since it is intended to supersede EFI_PROPERTIES_TABLE. */ if (efi_enabled(EFI_MEM_ATTR)) { + efi_disable_ibt_for_runtime = false; efi_memattr_apply_permissions(NULL, efi_update_mem_attr); return; }