Skip to content

Commit cf1d2ff

Browse files
committed
efi: Discover BTI support in runtime services regions
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 <[email protected]> Reviewed-by: Kees Cook <[email protected]>
1 parent b004809 commit cf1d2ff

File tree

9 files changed

+25
-11
lines changed

9 files changed

+25
-11
lines changed

arch/arm/include/asm/efi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void efi_init(void);
2020
void arm_efi_init(void);
2121

2222
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
23-
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
23+
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool);
2424

2525
#define arch_efi_call_virt_setup() efi_virtmap_load()
2626
#define arch_efi_call_virt_teardown() efi_virtmap_unload()

arch/arm/kernel/efi.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
2323
}
2424

2525
int __init efi_set_mapping_permissions(struct mm_struct *mm,
26-
efi_memory_desc_t *md)
26+
efi_memory_desc_t *md,
27+
bool ignored)
2728
{
2829
unsigned long base, size;
2930

@@ -71,7 +72,7 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
7172
* If stricter permissions were specified, apply them now.
7273
*/
7374
if (md->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))
74-
return efi_set_mapping_permissions(mm, md);
75+
return efi_set_mapping_permissions(mm, md, false);
7576
return 0;
7677
}
7778

arch/arm64/include/asm/efi.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ bool efi_runtime_fixup_exception(struct pt_regs *regs, const char *msg)
2727
#endif
2828

2929
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
30-
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
30+
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md,
31+
bool has_bti);
3132

3233
#define arch_efi_call_virt_setup() \
3334
({ \

arch/arm64/kernel/efi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
110110
}
111111

112112
int __init efi_set_mapping_permissions(struct mm_struct *mm,
113-
efi_memory_desc_t *md)
113+
efi_memory_desc_t *md,
114+
bool has_bti)
114115
{
115116
BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
116117
md->type != EFI_RUNTIME_SERVICES_DATA);

arch/riscv/include/asm/efi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extern void efi_init(void);
1919
#endif
2020

2121
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
22-
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
22+
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md, bool);
2323

2424
#define arch_efi_call_virt_setup() ({ \
2525
sync_kernel_mappings(efi_mm.pgd); \

arch/riscv/kernel/efi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
7878
}
7979

8080
int __init efi_set_mapping_permissions(struct mm_struct *mm,
81-
efi_memory_desc_t *md)
81+
efi_memory_desc_t *md,
82+
bool ignored)
8283
{
8384
BUG_ON(md->type != EFI_RUNTIME_SERVICES_CODE &&
8485
md->type != EFI_RUNTIME_SERVICES_DATA);

arch/x86/platform/efi/efi_64.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,8 @@ static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf)
389389
return err1 || err2;
390390
}
391391

392-
static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md)
392+
static int __init efi_update_mem_attr(struct mm_struct *mm, efi_memory_desc_t *md,
393+
bool has_ibt)
393394
{
394395
unsigned long pf = 0;
395396

drivers/firmware/efi/memattr.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm,
129129
efi_memattr_perm_setter fn)
130130
{
131131
efi_memory_attributes_table_t *tbl;
132+
bool has_bti = false;
132133
int i, ret;
133134

134135
if (tbl_size <= sizeof(*tbl))
@@ -150,6 +151,10 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm,
150151
return -ENOMEM;
151152
}
152153

154+
if (tbl->version > 1 &&
155+
(tbl->flags & EFI_MEMORY_ATTRIBUTES_FLAGS_RT_FORWARD_CONTROL_FLOW_GUARD))
156+
has_bti = true;
157+
153158
if (efi_enabled(EFI_DBG))
154159
pr_info("Processing EFI Memory Attributes table:\n");
155160

@@ -169,7 +174,7 @@ int __init efi_memattr_apply_permissions(struct mm_struct *mm,
169174
efi_md_typeattr_format(buf, sizeof(buf), &md));
170175

171176
if (valid) {
172-
ret = fn(mm, &md);
177+
ret = fn(mm, &md, has_bti);
173178
if (ret)
174179
pr_err("Error updating mappings, skipping subsequent md's\n");
175180
}

include/linux/efi.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,11 +584,15 @@ typedef struct {
584584

585585
#define EFI_INVALID_TABLE_ADDR (~0UL)
586586

587+
// BIT0 implies that Runtime code includes the forward control flow guard
588+
// instruction, such as X86 CET-IBT or ARM BTI.
589+
#define EFI_MEMORY_ATTRIBUTES_FLAGS_RT_FORWARD_CONTROL_FLOW_GUARD 0x1
590+
587591
typedef struct {
588592
u32 version;
589593
u32 num_entries;
590594
u32 desc_size;
591-
u32 reserved;
595+
u32 flags;
592596
efi_memory_desc_t entry[0];
593597
} efi_memory_attributes_table_t;
594598

@@ -751,7 +755,7 @@ extern unsigned long efi_mem_attr_table;
751755
* argument in the page tables referred to by the
752756
* first argument.
753757
*/
754-
typedef int (*efi_memattr_perm_setter)(struct mm_struct *, efi_memory_desc_t *);
758+
typedef int (*efi_memattr_perm_setter)(struct mm_struct *, efi_memory_desc_t *, bool);
755759

756760
extern int efi_memattr_init(void);
757761
extern int efi_memattr_apply_permissions(struct mm_struct *mm,

0 commit comments

Comments
 (0)