Skip to content

Commit 65f4aeb

Browse files
vathpelagregkh
authored andcommitted
efi: Don't map the entire mokvar table to determine its size
commit 2b90e7a upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent a3c5eb8 commit 65f4aeb

File tree

1 file changed

+13
-29
lines changed

1 file changed

+13
-29
lines changed

drivers/firmware/efi/mokvar-table.c

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,7 @@ 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;
108-
unsigned long size;
109107
struct efi_mokvar_table_entry *mokvar_entry;
110108
int err;
111109

@@ -134,48 +132,34 @@ void __init efi_mokvar_table_init(void)
134132
*/
135133
err = -EINVAL;
136134
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;
135+
if (va)
136+
early_memunmap(va, sizeof(*mokvar_entry));
137+
va = early_memremap(efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
138+
if (!va) {
139+
pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%zu.\n",
140+
efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
141+
return;
157142
}
143+
mokvar_entry = va;
158144

159145
/* Check for last sentinel entry */
160146
if (mokvar_entry->name[0] == '\0') {
161147
if (mokvar_entry->data_size != 0)
162148
break;
163149
err = 0;
150+
map_size_needed = cur_offset + sizeof(*mokvar_entry);
164151
break;
165152
}
166153

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;
154+
/* Enforce that the name is NUL terminated */
155+
mokvar_entry->name[sizeof(mokvar_entry->name) - 1] = '\0';
172156

173157
/* Advance to the next entry */
174-
cur_offset = map_size_needed + mokvar_entry->data_size;
158+
cur_offset += sizeof(*mokvar_entry) + mokvar_entry->data_size;
175159
}
176160

177161
if (va)
178-
early_memunmap(va, map_size);
162+
early_memunmap(va, sizeof(*mokvar_entry));
179163
if (err) {
180164
pr_err("EFI MOKvar config table is not valid\n");
181165
return;

0 commit comments

Comments
 (0)