diff options
author | Bob Moore <robert.moore@intel.com> | 2014-02-26 10:33:47 +0800 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-03-18 01:52:18 +0100 |
commit | f953529f3b659a72c0982c2cf195158db96361f1 (patch) | |
tree | 48eeb4fe487c2c0c82add70e8b71edea9a14f37d /drivers/acpi/acpica/evregion.c | |
parent | a487af33a4f0f5ced860ab18c4a740b97b435a3e (diff) | |
download | linux-f953529f3b659a72c0982c2cf195158db96361f1.tar.gz linux-f953529f3b659a72c0982c2cf195158db96361f1.tar.bz2 linux-f953529f3b659a72c0982c2cf195158db96361f1.zip |
ACPICA: Prevent infinite loops when traversing corrupted lists.
This change hardens the ACPICA code to detect circular linked object
lists and prevent an infinite loop if such corruption exists.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/acpica/evregion.c')
-rw-r--r-- | drivers/acpi/acpica/evregion.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c index e31049b3e9d4..9957297d1580 100644 --- a/drivers/acpi/acpica/evregion.c +++ b/drivers/acpi/acpica/evregion.c @@ -314,6 +314,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, { union acpi_operand_object *handler_obj; union acpi_operand_object *obj_desc; + union acpi_operand_object *start_desc; union acpi_operand_object **last_obj_ptr; acpi_adr_space_setup region_setup; void **region_context; @@ -341,6 +342,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, /* Find this region in the handler's list */ obj_desc = handler_obj->address_space.region_list; + start_desc = obj_desc; last_obj_ptr = &handler_obj->address_space.region_list; while (obj_desc) { @@ -438,6 +440,15 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, last_obj_ptr = &obj_desc->region.next; obj_desc = obj_desc->region.next; + + /* Prevent infinite loop if list is corrupted */ + + if (obj_desc == start_desc) { + ACPI_ERROR((AE_INFO, + "Circular handler list in region object %p", + region_obj)); + return_VOID; + } } /* If we get here, the region was not in the handler's region list */ |