diff options
author | Bob Moore <robert.moore@intel.com> | 2014-02-25 21:33:47 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-03-17 20:52:18 -0400 |
commit | f953529f3b659a72c0982c2cf195158db96361f1 (patch) | |
tree | 48eeb4fe487c2c0c82add70e8b71edea9a14f37d /drivers/acpi/acpica/evregion.c | |
parent | a487af33a4f0f5ced860ab18c4a740b97b435a3e (diff) |
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, | |||
314 | { | 314 | { |
315 | union acpi_operand_object *handler_obj; | 315 | union acpi_operand_object *handler_obj; |
316 | union acpi_operand_object *obj_desc; | 316 | union acpi_operand_object *obj_desc; |
317 | union acpi_operand_object *start_desc; | ||
317 | union acpi_operand_object **last_obj_ptr; | 318 | union acpi_operand_object **last_obj_ptr; |
318 | acpi_adr_space_setup region_setup; | 319 | acpi_adr_space_setup region_setup; |
319 | void **region_context; | 320 | void **region_context; |
@@ -341,6 +342,7 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, | |||
341 | /* Find this region in the handler's list */ | 342 | /* Find this region in the handler's list */ |
342 | 343 | ||
343 | obj_desc = handler_obj->address_space.region_list; | 344 | obj_desc = handler_obj->address_space.region_list; |
345 | start_desc = obj_desc; | ||
344 | last_obj_ptr = &handler_obj->address_space.region_list; | 346 | last_obj_ptr = &handler_obj->address_space.region_list; |
345 | 347 | ||
346 | while (obj_desc) { | 348 | while (obj_desc) { |
@@ -438,6 +440,15 @@ acpi_ev_detach_region(union acpi_operand_object *region_obj, | |||
438 | 440 | ||
439 | last_obj_ptr = &obj_desc->region.next; | 441 | last_obj_ptr = &obj_desc->region.next; |
440 | obj_desc = obj_desc->region.next; | 442 | obj_desc = obj_desc->region.next; |
443 | |||
444 | /* Prevent infinite loop if list is corrupted */ | ||
445 | |||
446 | if (obj_desc == start_desc) { | ||
447 | ACPI_ERROR((AE_INFO, | ||
448 | "Circular handler list in region object %p", | ||
449 | region_obj)); | ||
450 | return_VOID; | ||
451 | } | ||
441 | } | 452 | } |
442 | 453 | ||
443 | /* If we get here, the region was not in the handler's region list */ | 454 | /* If we get here, the region was not in the handler's region list */ |