Skip to content

Commit a37dac5

Browse files
committed
arm64: efi: Limit allocations to 48-bit addressable physical region
The UEFI spec does not mention or reason about the configured size of the virtual address space at all, but it does mention that all memory should be identity mapped using a page size of 4 KiB. This means that a LPA2 capable system that has any system memory outside of the 48-bit addressable physical range and follows the spec to the letter may serve page allocation requests from regions of memory that the kernel cannot access unless it was built with LPA2 support and enables it at runtime. So let's ensure that all page allocations are limited to the 48-bit range. Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent d9f26ae commit a37dac5

File tree

6 files changed

+13
-3
lines changed

6 files changed

+13
-3
lines changed

arch/arm64/include/asm/efi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ static inline unsigned long efi_get_kimg_min_align(void)
9292
}
9393

9494
#define EFI_ALLOC_ALIGN SZ_64K
95+
#define EFI_ALLOC_LIMIT ((1UL << 48) - 1)
9596

9697
/*
9798
* On ARM systems, virtually remapped UEFI runtime services are set up in two

drivers/firmware/efi/libstub/alignedmem.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr,
2929
efi_status_t status;
3030
int slack;
3131

32+
max = min(max, EFI_ALLOC_LIMIT);
33+
3234
if (align < EFI_ALLOC_ALIGN)
3335
align = EFI_ALLOC_ALIGN;
3436

drivers/firmware/efi/libstub/arm64-stub.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,11 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
113113
if (status != EFI_SUCCESS) {
114114
if (!check_image_region((u64)_text, kernel_memsize)) {
115115
efi_err("FIRMWARE BUG: Image BSS overlaps adjacent EFI memory region\n");
116-
} else if (IS_ALIGNED((u64)_text, min_kimg_align)) {
116+
} else if (IS_ALIGNED((u64)_text, min_kimg_align) &&
117+
(u64)_end < EFI_ALLOC_LIMIT) {
117118
/*
118119
* Just execute from wherever we were loaded by the
119-
* UEFI PE/COFF loader if the alignment is suitable.
120+
* UEFI PE/COFF loader if the placement is suitable.
120121
*/
121122
*image_addr = (u64)_text;
122123
*reserve_size = 0;

drivers/firmware/efi/libstub/efistub.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#define EFI_ALLOC_ALIGN EFI_PAGE_SIZE
3030
#endif
3131

32+
#ifndef EFI_ALLOC_LIMIT
33+
#define EFI_ALLOC_LIMIT ULONG_MAX
34+
#endif
35+
3236
extern bool efi_nochunk;
3337
extern bool efi_nokaslr;
3438
extern int efi_loglevel;

drivers/firmware/efi/libstub/mem.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
8989
efi_physical_addr_t alloc_addr;
9090
efi_status_t status;
9191

92+
max = min(max, EFI_ALLOC_LIMIT);
93+
9294
if (EFI_ALLOC_ALIGN > EFI_PAGE_SIZE)
9395
return efi_allocate_pages_aligned(size, addr, max,
9496
EFI_ALLOC_ALIGN,

drivers/firmware/efi/libstub/randomalloc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
2929
return 0;
3030

3131
region_end = min(md->phys_addr + md->num_pages * EFI_PAGE_SIZE - 1,
32-
(u64)ULONG_MAX);
32+
(u64)EFI_ALLOC_LIMIT);
3333
if (region_end < size)
3434
return 0;
3535

0 commit comments

Comments
 (0)