efi: libstub: use EFI_LOADER_CODE region when moving the kernel in memory
The EFI spec is not very clear about which permissions are being given when allocating pages of a certain type. However, it is quite obvious that EFI_LOADER_CODE is more likely to permit execution than EFI_LOADER_DATA, which becomes relevant once we permit booting the kernel proper with the firmware's 1:1 mapping still active. Ostensibly, recent systems such as the Surface Pro X grant executable permissions to EFI_LOADER_CODE regions but not EFI_LOADER_DATA regions. Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
977122898e
commit
9cf42bca30
|
@ -22,7 +22,8 @@
|
|||
* Return: status code
|
||||
*/
|
||||
efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr,
|
||||
unsigned long max, unsigned long align)
|
||||
unsigned long max, unsigned long align,
|
||||
int memory_type)
|
||||
{
|
||||
efi_physical_addr_t alloc_addr;
|
||||
efi_status_t status;
|
||||
|
@ -36,7 +37,7 @@ efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr,
|
|||
slack = align / EFI_PAGE_SIZE - 1;
|
||||
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
|
||||
EFI_LOADER_DATA, size / EFI_PAGE_SIZE + slack,
|
||||
memory_type, size / EFI_PAGE_SIZE + slack,
|
||||
&alloc_addr);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
|
|
@ -102,7 +102,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
|
|||
* locate the kernel at a randomized offset in physical memory.
|
||||
*/
|
||||
status = efi_random_alloc(*reserve_size, min_kimg_align,
|
||||
reserve_addr, phys_seed);
|
||||
reserve_addr, phys_seed,
|
||||
EFI_LOADER_CODE);
|
||||
if (status != EFI_SUCCESS)
|
||||
efi_warn("efi_random_alloc() failed: 0x%lx\n", status);
|
||||
} else {
|
||||
|
@ -123,7 +124,8 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
|
|||
}
|
||||
|
||||
status = efi_allocate_pages_aligned(*reserve_size, reserve_addr,
|
||||
ULONG_MAX, min_kimg_align);
|
||||
ULONG_MAX, min_kimg_align,
|
||||
EFI_LOADER_CODE);
|
||||
|
||||
if (status != EFI_SUCCESS) {
|
||||
efi_err("Failed to relocate kernel\n");
|
||||
|
|
|
@ -880,7 +880,8 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
|
|||
efi_status_t efi_get_random_bytes(unsigned long size, u8 *out);
|
||||
|
||||
efi_status_t efi_random_alloc(unsigned long size, unsigned long align,
|
||||
unsigned long *addr, unsigned long random_seed);
|
||||
unsigned long *addr, unsigned long random_seed,
|
||||
int memory_type);
|
||||
|
||||
efi_status_t check_platform_features(void);
|
||||
|
||||
|
@ -905,7 +906,8 @@ efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
|
|||
unsigned long max);
|
||||
|
||||
efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr,
|
||||
unsigned long max, unsigned long align);
|
||||
unsigned long max, unsigned long align,
|
||||
int memory_type);
|
||||
|
||||
efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
|
||||
unsigned long *addr, unsigned long min);
|
||||
|
|
|
@ -91,7 +91,8 @@ efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
|
|||
|
||||
if (EFI_ALLOC_ALIGN > EFI_PAGE_SIZE)
|
||||
return efi_allocate_pages_aligned(size, addr, max,
|
||||
EFI_ALLOC_ALIGN);
|
||||
EFI_ALLOC_ALIGN,
|
||||
EFI_LOADER_DATA);
|
||||
|
||||
alloc_addr = ALIGN_DOWN(max + 1, EFI_ALLOC_ALIGN) - 1;
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
|
||||
|
|
|
@ -53,7 +53,8 @@ static unsigned long get_entry_num_slots(efi_memory_desc_t *md,
|
|||
efi_status_t efi_random_alloc(unsigned long size,
|
||||
unsigned long align,
|
||||
unsigned long *addr,
|
||||
unsigned long random_seed)
|
||||
unsigned long random_seed,
|
||||
int memory_type)
|
||||
{
|
||||
unsigned long total_slots = 0, target_slot;
|
||||
unsigned long total_mirrored_slots = 0;
|
||||
|
@ -118,7 +119,7 @@ efi_status_t efi_random_alloc(unsigned long size,
|
|||
pages = size / EFI_PAGE_SIZE;
|
||||
|
||||
status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
|
||||
EFI_LOADER_DATA, pages, &target);
|
||||
memory_type, pages, &target);
|
||||
if (status == EFI_SUCCESS)
|
||||
*addr = target;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue