aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/evregion.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2014-02-25 21:33:47 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-03-17 20:52:18 -0400
commitf953529f3b659a72c0982c2cf195158db96361f1 (patch)
tree48eeb4fe487c2c0c82add70e8b71edea9a14f37d /drivers/acpi/acpica/evregion.c
parenta487af33a4f0f5ced860ab18c4a740b97b435a3e (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.c11
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 */