Skip to content

Commit 1d95931

Browse files
committed
efi: arm64: Wire up BTI annotation in memory attributes table
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 <[email protected]> Reviewed-by: Kees Cook <[email protected]> Acked-by: Mark Rutland <[email protected]> Reviewed-by: Will Deacon <[email protected]>
1 parent cf1d2ff commit 1d95931

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

arch/arm64/kernel/efi.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,24 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
9696
return 0;
9797
}
9898

99+
struct set_perm_data {
100+
const efi_memory_desc_t *md;
101+
bool has_bti;
102+
};
103+
99104
static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
100105
{
101-
efi_memory_desc_t *md = data;
106+
struct set_perm_data *spd = data;
107+
const efi_memory_desc_t *md = spd->md;
102108
pte_t pte = READ_ONCE(*ptep);
103109

104110
if (md->attribute & EFI_MEMORY_RO)
105111
pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
106112
if (md->attribute & EFI_MEMORY_XP)
107113
pte = set_pte_bit(pte, __pgprot(PTE_PXN));
114+
else if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) &&
115+
system_supports_bti() && spd->has_bti)
116+
pte = set_pte_bit(pte, __pgprot(PTE_GP));
108117
set_pte(ptep, pte);
109118
return 0;
110119
}
@@ -113,6 +122,8 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm,
113122
efi_memory_desc_t *md,
114123
bool has_bti)
115124
{
125+
struct set_perm_data data = { md, has_bti };
126+
116127
BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
117128
md->type != EFI_RUNTIME_SERVICES_DATA);
118129

@@ -128,7 +139,7 @@ int __init efi_set_mapping_permissions(struct mm_struct *mm,
128139
*/
129140
return apply_to_page_range(mm, md->virt_addr,
130141
md->num_pages << EFI_PAGE_SHIFT,
131-
set_permissions, md);
142+
set_permissions, &data);
132143
}
133144

134145
/*

arch/arm64/kernel/traps.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/module.h>
1919
#include <linux/kexec.h>
2020
#include <linux/delay.h>
21+
#include <linux/efi.h>
2122
#include <linux/init.h>
2223
#include <linux/sched/signal.h>
2324
#include <linux/sched/debug.h>
@@ -33,6 +34,7 @@
3334
#include <asm/cpufeature.h>
3435
#include <asm/daifflags.h>
3536
#include <asm/debug-monitors.h>
37+
#include <asm/efi.h>
3638
#include <asm/esr.h>
3739
#include <asm/exception.h>
3840
#include <asm/extable.h>
@@ -492,6 +494,10 @@ void do_el0_bti(struct pt_regs *regs)
492494

493495
void do_el1_bti(struct pt_regs *regs, unsigned long esr)
494496
{
497+
if (efi_runtime_fixup_exception(regs, "BTI violation")) {
498+
regs->pstate &= ~PSR_BTYPE_MASK;
499+
return;
500+
}
495501
die("Oops - BTI", regs, esr);
496502
}
497503

0 commit comments

Comments
 (0)