diff options
| -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 |
