36 lines
1.2 KiB
Diff
36 lines
1.2 KiB
Diff
|
# Commit 9c1e8cae657bc13e8b1ddeede17603d77f3ad341
|
||
|
# Date 2014-06-04 11:26:15 +0200
|
||
|
# Author Malcolm Crossley <malcolm.crossley@citrix.com>
|
||
|
# Committer Jan Beulich <jbeulich@suse.com>
|
||
|
ACPI: Prevent acpi_table_entries from falling into a infinite loop
|
||
|
|
||
|
If a buggy BIOS programs an ACPI table with to small an entry length
|
||
|
then acpi_table_entries gets stuck in an infinite loop.
|
||
|
|
||
|
To aid debugging, report the error and exit the loop.
|
||
|
|
||
|
Based on Linux kernel commit 369d913b242cae2205471b11b6e33ac368ed33ec
|
||
|
|
||
|
Signed-off-by: Malcolm Crossley <malcolm.crossley@citrix.com>
|
||
|
|
||
|
Use < instead of <= (which I wrongly suggested), return -ENODATA
|
||
|
instead of -EINVAL, and make description match code.
|
||
|
|
||
|
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
||
|
|
||
|
--- a/xen/drivers/acpi/tables.c
|
||
|
+++ b/xen/drivers/acpi/tables.c
|
||
|
@@ -233,6 +233,12 @@ acpi_table_parse_entries(char *id,
|
||
|
|
||
|
while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
|
||
|
table_end) {
|
||
|
+ if (entry->length < sizeof(*entry)) {
|
||
|
+ printk(KERN_ERR PREFIX "[%4.4s:%#x] Invalid length\n",
|
||
|
+ id, entry_id);
|
||
|
+ return -ENODATA;
|
||
|
+ }
|
||
|
+
|
||
|
if (entry->type == entry_id
|
||
|
&& (!max_entries || count++ < max_entries))
|
||
|
if (handler(entry, table_end))
|