Skip to content

Commit 9fc68b7

Browse files
Ard BiesheuvelIngo Molnar
authored andcommitted
ARM/efi: Apply strict permissions for UEFI Runtime Services regions
Recent UEFI versions expose permission attributes for runtime services memory regions, either in the UEFI memory map or in the separate memory attributes table. This allows the kernel to map these regions with stricter permissions, rather than the RWX permissions that are used by default. So wire this up in our mapping routine. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk> Cc: Borislav Petkov <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Leif Lindholm <leif.lindholm@linaro.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Peter Jones <pjones@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Russell King <rmk+kernel@arm.linux.org.uk> Cc: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Will Deacon <will.deacon@arm.com> Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1461614832-17633-11-git-send-email-matt@codeblueprint.co.uk Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 24d45d1 commit 9fc68b7

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

arch/arm/include/asm/efi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
void efi_init(void);
2323

2424
int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
25+
int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
2526

2627
#define efi_call_virt(f, ...) \
2728
({ \

arch/arm/kernel/efi.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,41 @@
1111
#include <asm/mach/map.h>
1212
#include <asm/mmu_context.h>
1313

14+
static int __init set_permissions(pte_t *ptep, pgtable_t token,
15+
unsigned long addr, void *data)
16+
{
17+
efi_memory_desc_t *md = data;
18+
pte_t pte = *ptep;
19+
20+
if (md->attribute & EFI_MEMORY_RO)
21+
pte = set_pte_bit(pte, __pgprot(L_PTE_RDONLY));
22+
if (md->attribute & EFI_MEMORY_XP)
23+
pte = set_pte_bit(pte, __pgprot(L_PTE_XN));
24+
set_pte_ext(ptep, pte, PTE_EXT_NG);
25+
return 0;
26+
}
27+
28+
int __init efi_set_mapping_permissions(struct mm_struct *mm,
29+
efi_memory_desc_t *md)
30+
{
31+
unsigned long base, size;
32+
33+
base = md->virt_addr;
34+
size = md->num_pages << EFI_PAGE_SHIFT;
35+
36+
/*
37+
* We can only use apply_to_page_range() if we can guarantee that the
38+
* entire region was mapped using pages. This should be the case if the
39+
* region does not cover any naturally aligned SECTION_SIZE sized
40+
* blocks.
41+
*/
42+
if (round_down(base + size, SECTION_SIZE) <
43+
round_up(base, SECTION_SIZE) + SECTION_SIZE)
44+
return apply_to_page_range(mm, base, size, set_permissions, md);
45+
46+
return 0;
47+
}
48+
1449
int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
1550
{
1651
struct map_desc desc = {
@@ -34,5 +69,11 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md)
3469
desc.type = MT_DEVICE;
3570

3671
create_mapping_late(mm, &desc, true);
72+
73+
/*
74+
* If stricter permissions were specified, apply them now.
75+
*/
76+
if (md->attribute & (EFI_MEMORY_RO | EFI_MEMORY_XP))
77+
return efi_set_mapping_permissions(mm, md);
3778
return 0;
3879
}

0 commit comments

Comments
 (0)