diff options
Diffstat (limited to 'drivers/acpi/tables.c')
-rw-r--r-- | drivers/acpi/tables.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index f336bca7c450..2572d9715bda 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c | |||
@@ -240,10 +240,17 @@ acpi_table_parse_entries(char *id, | |||
240 | table_end) { | 240 | table_end) { |
241 | if (entry->type == entry_id | 241 | if (entry->type == entry_id |
242 | && (!max_entries || count++ < max_entries)) | 242 | && (!max_entries || count++ < max_entries)) |
243 | if (handler(entry, table_end)) { | 243 | if (handler(entry, table_end)) |
244 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | 244 | goto err; |
245 | return -EINVAL; | 245 | |
246 | } | 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 | entry = (struct acpi_subtable_header *) | 255 | entry = (struct acpi_subtable_header *) |
249 | ((unsigned long)entry + entry->length); | 256 | ((unsigned long)entry + entry->length); |
@@ -255,6 +262,9 @@ acpi_table_parse_entries(char *id, | |||
255 | 262 | ||
256 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | 263 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); |
257 | return count; | 264 | return count; |
265 | err: | ||
266 | early_acpi_os_unmap_memory((char *)table_header, tbl_size); | ||
267 | return -EINVAL; | ||
258 | } | 268 | } |
259 | 269 | ||
260 | int __init | 270 | int __init |