Skip to content

Commit a7a6a01

Browse files
committed
x86/efistub: Give up if memory attribute protocol returns an error
The recently introduced EFI memory attributes protocol should be used if it exists to ensure that the memory allocation created for the kernel permits execution. This is needed for compatibility with tightened requirements related to Windows logo certification for x86 PCs. Currently, we simply strip the execute protect (XP) attribute from the entire range, but this might be rejected under some firmware security policies, and so in a subsequent patch, this will be changed to only strip XP from the executable region that runs early, and make it read-only (RO) as well. In order to catch any issues early, ensure that the memory attribute protocol works as intended, and give up if it produces spurious errors. Note that the DXE services based fallback was always based on best effort, so don't propagate any errors returned by that API. Fixes: a1b87d5 ("x86/efistub: Avoid legacy decompressor when doing EFI boot") Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent d2baf8c commit a7a6a01

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

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

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params)
223223
}
224224
}
225225

226-
void efi_adjust_memory_range_protection(unsigned long start,
227-
unsigned long size)
226+
efi_status_t efi_adjust_memory_range_protection(unsigned long start,
227+
unsigned long size)
228228
{
229229
efi_status_t status;
230230
efi_gcd_memory_space_desc_t desc;
@@ -236,13 +236,17 @@ void efi_adjust_memory_range_protection(unsigned long start,
236236
rounded_end = roundup(start + size, EFI_PAGE_SIZE);
237237

238238
if (memattr != NULL) {
239-
efi_call_proto(memattr, clear_memory_attributes, rounded_start,
240-
rounded_end - rounded_start, EFI_MEMORY_XP);
241-
return;
239+
status = efi_call_proto(memattr, clear_memory_attributes,
240+
rounded_start,
241+
rounded_end - rounded_start,
242+
EFI_MEMORY_XP);
243+
if (status != EFI_SUCCESS)
244+
efi_warn("Failed to clear EFI_MEMORY_XP attribute\n");
245+
return status;
242246
}
243247

244248
if (efi_dxe_table == NULL)
245-
return;
249+
return EFI_SUCCESS;
246250

247251
/*
248252
* Don't modify memory region attributes, they are
@@ -255,7 +259,7 @@ void efi_adjust_memory_range_protection(unsigned long start,
255259
status = efi_dxe_call(get_memory_space_descriptor, start, &desc);
256260

257261
if (status != EFI_SUCCESS)
258-
return;
262+
break;
259263

260264
next = desc.base_address + desc.length;
261265

@@ -280,8 +284,10 @@ void efi_adjust_memory_range_protection(unsigned long start,
280284
unprotect_start,
281285
unprotect_start + unprotect_size,
282286
status);
287+
break;
283288
}
284289
}
290+
return EFI_SUCCESS;
285291
}
286292

287293
static void setup_unaccepted_memory(void)
@@ -805,9 +811,7 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
805811

806812
*kernel_entry = addr + entry;
807813

808-
efi_adjust_memory_range_protection(addr, kernel_total_size);
809-
810-
return EFI_SUCCESS;
814+
return efi_adjust_memory_range_protection(addr, kernel_total_size);
811815
}
812816

813817
static void __noreturn enter_kernel(unsigned long kernel_addr,

drivers/firmware/efi/libstub/x86-stub.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
extern void trampoline_32bit_src(void *, bool);
66
extern const u16 trampoline_ljmp_imm_offset;
77

8-
void efi_adjust_memory_range_protection(unsigned long start,
9-
unsigned long size);
8+
efi_status_t efi_adjust_memory_range_protection(unsigned long start,
9+
unsigned long size);
1010

1111
#ifdef CONFIG_X86_64
1212
efi_status_t efi_setup_5level_paging(void);

0 commit comments

Comments
 (0)