Skip to content

Commit 2b90e7a

Browse files
vathpelaardbiesheuvel
authored andcommitted
efi: Don't map the entire mokvar table to determine its size
Currently, when validating the mokvar table, we (re)map the entire table on each iteration of the loop, adding space as we discover new entries. If the table grows over a certain size, this fails due to limitations of early_memmap(), and we get a failure and traceback: ------------[ cut here ]------------ WARNING: CPU: 0 PID: 0 at mm/early_ioremap.c:139 __early_ioremap+0xef/0x220 ... Call Trace: <TASK> ? __early_ioremap+0xef/0x220 ? __warn.cold+0x93/0xfa ? __early_ioremap+0xef/0x220 ? report_bug+0xff/0x140 ? early_fixup_exception+0x5d/0xb0 ? early_idt_handler_common+0x2f/0x3a ? __early_ioremap+0xef/0x220 ? efi_mokvar_table_init+0xce/0x1d0 ? setup_arch+0x864/0xc10 ? start_kernel+0x6b/0xa10 ? x86_64_start_reservations+0x24/0x30 ? x86_64_start_kernel+0xed/0xf0 ? common_startup_64+0x13e/0x141 </TASK> ---[ end trace 0000000000000000 ]--- mokvar: Failed to map EFI MOKvar config table pa=0x7c4c3000, size=265187. Mapping the entire structure isn't actually necessary, as we don't ever need more than one entry header mapped at once. Changes efi_mokvar_table_init() to only map each entry header, not the entire table, when determining the table size. Since we're not mapping any data past the variable name, it also changes the code to enforce that each variable name is NUL terminated, rather than attempting to verify it in place. Cc: <stable@vger.kernel.org> Signed-off-by: Peter Jones <pjones@redhat.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent fc20737 commit 2b90e7a

File tree

1 file changed

+13
-28
lines changed

1 file changed

+13
-28
lines changed

drivers/firmware/efi/mokvar-table.c

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ void __init efi_mokvar_table_init(void)
103103
void *va = NULL;
104104
unsigned long cur_offset = 0;
105105
unsigned long offset_limit;
106-
unsigned long map_size = 0;
107106
unsigned long map_size_needed = 0;
108107
unsigned long size;
109108
struct efi_mokvar_table_entry *mokvar_entry;
@@ -134,48 +133,34 @@ void __init efi_mokvar_table_init(void)
134133
*/
135134
err = -EINVAL;
136135
while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
137-
mokvar_entry = va + cur_offset;
138-
map_size_needed = cur_offset + sizeof(*mokvar_entry);
139-
if (map_size_needed > map_size) {
140-
if (va)
141-
early_memunmap(va, map_size);
142-
/*
143-
* Map a little more than the fixed size entry
144-
* header, anticipating some data. It's safe to
145-
* do so as long as we stay within current memory
146-
* descriptor.
147-
*/
148-
map_size = min(map_size_needed + 2*EFI_PAGE_SIZE,
149-
offset_limit);
150-
va = early_memremap(efi.mokvar_table, map_size);
151-
if (!va) {
152-
pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n",
153-
efi.mokvar_table, map_size);
154-
return;
155-
}
156-
mokvar_entry = va + cur_offset;
136+
if (va)
137+
early_memunmap(va, sizeof(*mokvar_entry));
138+
va = early_memremap(efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
139+
if (!va) {
140+
pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%zu.\n",
141+
efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
142+
return;
157143
}
144+
mokvar_entry = va;
158145

159146
/* Check for last sentinel entry */
160147
if (mokvar_entry->name[0] == '\0') {
161148
if (mokvar_entry->data_size != 0)
162149
break;
163150
err = 0;
151+
map_size_needed = cur_offset + sizeof(*mokvar_entry);
164152
break;
165153
}
166154

167-
/* Sanity check that the name is null terminated */
168-
size = strnlen(mokvar_entry->name,
169-
sizeof(mokvar_entry->name));
170-
if (size >= sizeof(mokvar_entry->name))
171-
break;
155+
/* Enforce that the name is NUL terminated */
156+
mokvar_entry->name[sizeof(mokvar_entry->name) - 1] = '\0';
172157

173158
/* Advance to the next entry */
174-
cur_offset = map_size_needed + mokvar_entry->data_size;
159+
cur_offset += sizeof(*mokvar_entry) + mokvar_entry->data_size;
175160
}
176161

177162
if (va)
178-
early_memunmap(va, map_size);
163+
early_memunmap(va, sizeof(*mokvar_entry));
179164
if (err) {
180165
pr_err("EFI MOKvar config table is not valid\n");
181166
return;

0 commit comments

Comments
 (0)