efi: Align unaccepted memory range to page boundary
The accept_memory() and range_contains_unaccepted_memory() functions employ a "guard page" logic to prevent crashes with load_unaligned_zeropad(). This logic extends the range to be accepted (or checked) by one unit_size if the end of the range is aligned to a unit_size boundary. However, if the caller passes a range that is not page-aligned, the 'end' of the range might not be numerically aligned to unit_size, even if it covers the last page of a unit. This causes the "if (!(end % unit_size))" check to fail, skipping the necessary extension and leaving the next unit unaccepted, which can lead to a kernel panic when accessed by load_unaligned_zeropad(). Align the start address down and the size up to the nearest page boundary before performing the unit_size alignment check. This ensures that the guard unit is correctly added when the range effectively ends on a unit boundary. Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
parent
0862438c90
commit
948a013a54
|
|
@ -35,14 +35,17 @@ void accept_memory(phys_addr_t start, unsigned long size)
|
|||
struct efi_unaccepted_memory *unaccepted;
|
||||
unsigned long range_start, range_end;
|
||||
struct accept_range range, *entry;
|
||||
phys_addr_t end = start + size;
|
||||
unsigned long flags;
|
||||
phys_addr_t end;
|
||||
u64 unit_size;
|
||||
|
||||
unaccepted = efi_get_unaccepted_table();
|
||||
if (!unaccepted)
|
||||
return;
|
||||
|
||||
end = PAGE_ALIGN(start + size);
|
||||
start = PAGE_ALIGN_DOWN(start);
|
||||
|
||||
unit_size = unaccepted->unit_size;
|
||||
|
||||
/*
|
||||
|
|
@ -160,15 +163,18 @@ retry:
|
|||
bool range_contains_unaccepted_memory(phys_addr_t start, unsigned long size)
|
||||
{
|
||||
struct efi_unaccepted_memory *unaccepted;
|
||||
phys_addr_t end = start + size;
|
||||
unsigned long flags;
|
||||
bool ret = false;
|
||||
phys_addr_t end;
|
||||
u64 unit_size;
|
||||
|
||||
unaccepted = efi_get_unaccepted_table();
|
||||
if (!unaccepted)
|
||||
return false;
|
||||
|
||||
end = PAGE_ALIGN(start + size);
|
||||
start = PAGE_ALIGN_DOWN(start);
|
||||
|
||||
unit_size = unaccepted->unit_size;
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue