Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI: Harden acpi_table_parse_entries() against BIOS bug

Parsing acpi table entries may fall into an infinite loop on a buggy BIOS
which has entry length=0 in acpi table.

Instead of kernel hang with few failure clue which leads to heavy lifting debug
effort, this patch hardens kernel boot by booting into non NUMA mode. The debug
info left in log buffer helps people identify the issue.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

authored by

Fenghua Yu and committed by
Len Brown
369d913b fc54ab72

+14 -4
+14 -4
drivers/acpi/tables.c
··· 240 240 table_end) { 241 241 if (entry->type == entry_id 242 242 && (!max_entries || count++ < max_entries)) 243 - if (handler(entry, table_end)) { 244 - early_acpi_os_unmap_memory((char *)table_header, tbl_size); 245 - return -EINVAL; 246 - } 243 + if (handler(entry, table_end)) 244 + goto err; 245 + 246 + /* 247 + * If entry->length is 0, break from this loop to avoid 248 + * infinite loop. 249 + */ 250 + if (entry->length == 0) { 251 + pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); 252 + goto err; 253 + } 247 254 248 255 entry = (struct acpi_subtable_header *) 249 256 ((unsigned long)entry + entry->length); ··· 262 255 263 256 early_acpi_os_unmap_memory((char *)table_header, tbl_size); 264 257 return count; 258 + err: 259 + early_acpi_os_unmap_memory((char *)table_header, tbl_size); 260 + return -EINVAL; 265 261 } 266 262 267 263 int __init