Skip to content

Commit 8fbe4c4

Browse files
committed
efi/memattr: Ignore table if the size is clearly bogus
There are reports [0] of cases where a corrupt EFI Memory Attributes Table leads to out of memory issues at boot because the descriptor size and entry count in the table header are still used to reserve the entire table in memory, even though the resulting region is gigabytes in size. Given that the EFI Memory Attributes Table is supposed to carry up to 3 entries for each EfiRuntimeServicesCode region in the EFI memory map, and given that there is no reason for the descriptor size used in the table to exceed the one used in the EFI memory map, 3x the size of the entire EFI memory map is a reasonable upper bound for the size of this table. This means that sizes exceeding that are highly likely to be based on corrupted data, and the table should just be ignored instead. [0] https://bugzilla.suse.com/show_bug.cgi?id=1231465 Cc: Gregory Price <gourry@gourry.net> Cc: Usama Arif <usamaarif642@gmail.com> Acked-by: Jiri Slaby <jirislaby@kernel.org> Acked-by: Breno Leitao <leitao@debian.org> Link: https://lore.kernel.org/all/20240912155159.1951792-2-ardb+git@google.com/ Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 6fce6e9 commit 8fbe4c4

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

drivers/firmware/efi/memattr.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ unsigned long __ro_after_init efi_mem_attr_table = EFI_INVALID_TABLE_ADDR;
2222
int __init efi_memattr_init(void)
2323
{
2424
efi_memory_attributes_table_t *tbl;
25+
unsigned long size;
2526

2627
if (efi_mem_attr_table == EFI_INVALID_TABLE_ADDR)
2728
return 0;
@@ -39,7 +40,22 @@ int __init efi_memattr_init(void)
3940
goto unmap;
4041
}
4142

42-
tbl_size = sizeof(*tbl) + tbl->num_entries * tbl->desc_size;
43+
44+
/*
45+
* Sanity check: the Memory Attributes Table contains up to 3 entries
46+
* for each entry of type EfiRuntimeServicesCode in the EFI memory map.
47+
* So if the size of the table exceeds 3x the size of the entire EFI
48+
* memory map, there is clearly something wrong, and the table should
49+
* just be ignored altogether.
50+
*/
51+
size = tbl->num_entries * tbl->desc_size;
52+
if (size > 3 * efi.memmap.nr_map * efi.memmap.desc_size) {
53+
pr_warn(FW_BUG "Corrupted EFI Memory Attributes Table detected! (version == %u, desc_size == %u, num_entries == %u)\n",
54+
tbl->version, tbl->desc_size, tbl->num_entries);
55+
goto unmap;
56+
}
57+
58+
tbl_size = sizeof(*tbl) + size;
4359
memblock_reserve(efi_mem_attr_table, tbl_size);
4460
set_bit(EFI_MEM_ATTR, &efi.flags);
4561

0 commit comments

Comments
 (0)