acpi_parse_entries passes the table end pointer to the sub-table entry handler. acpi_parse_entries itself could validate the end of an entry against the table end using the length in the sub-table entry. This patch adds the validation of the sub-table entry end using the length field.This will help to eliminate the need to pass the table end to the handlers. Cc: "Rafael J. Wysocki" <rjw@xxxxxxxxxxxxx> Signed-off-by: Sudeep Holla <sudeep.holla@xxxxxxx> --- drivers/acpi/tables.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c index 17a6fa01a338..145d4f6a1c54 100644 --- a/drivers/acpi/tables.c +++ b/drivers/acpi/tables.c @@ -217,16 +217,13 @@ acpi_parse_entries(char *id, unsigned long table_size, int entry_id, unsigned int max_entries) { struct acpi_subtable_header *entry; + void *entry_end, *table_end; int count = 0; - unsigned long table_end; if (acpi_disabled) return -ENODEV; - if (!id || !handler) - return -EINVAL; - - if (!table_size) + if (!id || !handler || !table_size) return -EINVAL; if (!table_header) { @@ -234,34 +231,21 @@ acpi_parse_entries(char *id, unsigned long table_size, return -ENODEV; } - table_end = (unsigned long)table_header + table_header->length; + table_end = (void *)table_header + table_header->length; /* Parse all entries looking for a match. */ + entry = (void *)table_header + table_size; + entry_end = (void *)entry + entry->length; - entry = (struct acpi_subtable_header *) - ((unsigned long)table_header + table_size); - - while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < - table_end) { + while (entry->length && entry_end <= table_end) { if (entry->type == entry_id && (!max_entries || count < max_entries)) { - if (handler(entry, table_end)) + if (handler(entry, (unsigned long)entry_end)) return -EINVAL; - count++; } - - /* - * If entry->length is 0, break from this loop to avoid - * infinite loop. - */ - if (entry->length == 0) { - pr_err("[%4.4s:0x%02x] Invalid zero length\n", id, entry_id); - return -EINVAL; - } - - entry = (struct acpi_subtable_header *) - ((unsigned long)entry + entry->length); + entry = entry_end; + entry_end = (void *)entry + entry->length; } if (max_entries && count > max_entries) { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html