linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] efi: Enable BTI for EFI runtimes services
@ 2023-02-01 13:25 Ard Biesheuvel
  2023-02-01 13:25 ` [PATCH 1/2] efi: Discover BTI support in runtime services regions Ard Biesheuvel
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-01 13:25 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, Ard Biesheuvel, Catalin Marinas, Will Deacon,
	Kees Cook, Mark Rutland

The EFI spec v2.10 introduces a global flag in the memory attributes
table that indicates whether the EFI runtime code regions were emitted
with BTI landing pads, and can therefore tolerate being mapped with BTI
enforcement enabled.

Add the generic plumbing for this, and wire it up for arm64.

Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mark Rutland <mark.rutland@arm.com>

Ard Biesheuvel (2):
  efi: Discover BTI support in runtime services regions
  efi: arm64: Wire up BTI annotation in memory attributes table

 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        | 18 +++++++++++++++---
 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 |  9 +++++++--
 include/linux/efi.h            |  8 ++++++--
 9 files changed, 39 insertions(+), 14 deletions(-)

-- 
2.39.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] efi: Discover BTI support in runtime services regions
  2023-02-01 13:25 [PATCH 0/2] efi: Enable BTI for EFI runtimes services Ard Biesheuvel
@ 2023-02-01 13:25 ` Ard Biesheuvel
  2023-02-01 13:25 ` [PATCH 2/2] efi: arm64: Wire up BTI annotation in memory attributes table Ard Biesheuvel
  2023-02-02 17:37 ` [PATCH 0/2] efi: Enable BTI for EFI runtimes services Kees Cook
  2 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-01 13:25 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, Ard Biesheuvel, Catalin Marinas, Will Deacon,
	Kees Cook, Mark Rutland

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 <ardb@kernel.org>
---
 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 | 9 +++++++--
 include/linux/efi.h            | 8 ++++++--
 9 files changed, 26 insertions(+), 12 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 acaa39f6381a084b..8adca3b83c62a52b 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 b273900f45668587..908499486b00274e 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -111,7 +111,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..ab85bf8e165a3575 100644
--- a/drivers/firmware/efi/memattr.c
+++ b/drivers/firmware/efi/memattr.c
@@ -33,7 +33,7 @@ int __init efi_memattr_init(void)
 		return -ENOMEM;
 	}
 
-	if (tbl->version > 1) {
+	if (tbl->version > 2) {
 		pr_warn("Unexpected EFI Memory Attributes table version %d\n",
 			tbl->version);
 		goto unmap;
@@ -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 507390dda8b9c2f2..3ba27f34fe445aa3 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;
 
@@ -752,7 +756,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,
-- 
2.39.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] efi: arm64: Wire up BTI annotation in memory attributes table
  2023-02-01 13:25 [PATCH 0/2] efi: Enable BTI for EFI runtimes services Ard Biesheuvel
  2023-02-01 13:25 ` [PATCH 1/2] efi: Discover BTI support in runtime services regions Ard Biesheuvel
@ 2023-02-01 13:25 ` Ard Biesheuvel
  2023-02-02 17:37 ` [PATCH 0/2] efi: Enable BTI for EFI runtimes services Kees Cook
  2 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-01 13:25 UTC (permalink / raw)
  To: linux-efi
  Cc: linux-arm-kernel, Ard Biesheuvel, Catalin Marinas, Will Deacon,
	Kees Cook, Mark Rutland

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 <ardb@kernel.org>
---
 arch/arm64/kernel/efi.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 908499486b00274e..6a61553b64c51dcd 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -97,15 +97,24 @@ 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 (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) &&
+		 system_supports_bti() && spd->has_bti)
+		pte = set_pte_bit(pte, __pgprot(PTE_GP));
 	set_pte(ptep, pte);
 	return 0;
 }
@@ -114,6 +123,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);
 
@@ -129,7 +140,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);
 }
 
 /*
-- 
2.39.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] efi: Enable BTI for EFI runtimes services
  2023-02-01 13:25 [PATCH 0/2] efi: Enable BTI for EFI runtimes services Ard Biesheuvel
  2023-02-01 13:25 ` [PATCH 1/2] efi: Discover BTI support in runtime services regions Ard Biesheuvel
  2023-02-01 13:25 ` [PATCH 2/2] efi: arm64: Wire up BTI annotation in memory attributes table Ard Biesheuvel
@ 2023-02-02 17:37 ` Kees Cook
  2023-02-04  8:23   ` Ard Biesheuvel
  2 siblings, 1 reply; 5+ messages in thread
From: Kees Cook @ 2023-02-02 17:37 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, linux-arm-kernel, Catalin Marinas, Will Deacon,
	Mark Rutland

On Wed, Feb 01, 2023 at 02:25:38PM +0100, Ard Biesheuvel wrote:
> The EFI spec v2.10 introduces a global flag in the memory attributes
> table that indicates whether the EFI runtime code regions were emitted
> with BTI landing pads, and can therefore tolerate being mapped with BTI
> enforcement enabled.
> 
> Add the generic plumbing for this, and wire it up for arm64.

Looks nice! :)

Reviewed-by: Kees Cook <keescook@chromium.org>

> 
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> 
> Ard Biesheuvel (2):
>   efi: Discover BTI support in runtime services regions
>   efi: arm64: Wire up BTI annotation in memory attributes table
> 
>  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        | 18 +++++++++++++++---
>  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 |  9 +++++++--
>  include/linux/efi.h            |  8 ++++++--
>  9 files changed, 39 insertions(+), 14 deletions(-)
> 
> -- 
> 2.39.0
> 

-- 
Kees Cook

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] efi: Enable BTI for EFI runtimes services
  2023-02-02 17:37 ` [PATCH 0/2] efi: Enable BTI for EFI runtimes services Kees Cook
@ 2023-02-04  8:23   ` Ard Biesheuvel
  0 siblings, 0 replies; 5+ messages in thread
From: Ard Biesheuvel @ 2023-02-04  8:23 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-efi, linux-arm-kernel, Catalin Marinas, Will Deacon,
	Mark Rutland

On Thu, 2 Feb 2023 at 18:37, Kees Cook <keescook@chromium.org> wrote:
>
> On Wed, Feb 01, 2023 at 02:25:38PM +0100, Ard Biesheuvel wrote:
> > The EFI spec v2.10 introduces a global flag in the memory attributes
> > table that indicates whether the EFI runtime code regions were emitted
> > with BTI landing pads, and can therefore tolerate being mapped with BTI
> > enforcement enabled.
> >
> > Add the generic plumbing for this, and wire it up for arm64.
>
> Looks nice! :)
>
> Reviewed-by: Kees Cook <keescook@chromium.org>
>

Thanks

I've queued these up now in efi/next


> >
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Kees Cook <keescook@chromium.org>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> >
> > Ard Biesheuvel (2):
> >   efi: Discover BTI support in runtime services regions
> >   efi: arm64: Wire up BTI annotation in memory attributes table
> >
> >  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        | 18 +++++++++++++++---
> >  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 |  9 +++++++--
> >  include/linux/efi.h            |  8 ++++++--
> >  9 files changed, 39 insertions(+), 14 deletions(-)
> >
> > --
> > 2.39.0
> >
>
> --
> Kees Cook

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-02-04  8:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-01 13:25 [PATCH 0/2] efi: Enable BTI for EFI runtimes services Ard Biesheuvel
2023-02-01 13:25 ` [PATCH 1/2] efi: Discover BTI support in runtime services regions Ard Biesheuvel
2023-02-01 13:25 ` [PATCH 2/2] efi: arm64: Wire up BTI annotation in memory attributes table Ard Biesheuvel
2023-02-02 17:37 ` [PATCH 0/2] efi: Enable BTI for EFI runtimes services Kees Cook
2023-02-04  8:23   ` Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).