diff options
| -rw-r--r-- | drivers/acpi/acpica/evregion.c | 11 | ||||
| -rw-r--r-- | drivers/acpi/acpica/nsobject.c | 10 | ||||
| -rw-r--r-- | drivers/acpi/acpica/utdelete.c | 15 |
3 files changed, 32 insertions, 4 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 */ |
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c index 32845b105053..fe54a8c73b8c 100644 --- a/drivers/acpi/acpica/nsobject.c +++ b/drivers/acpi/acpica/nsobject.c | |||
| @@ -222,13 +222,19 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) | |||
| 222 | } | 222 | } |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | /* Clear the entry in all cases */ | 225 | /* Clear the Node entry in all cases */ |
| 226 | 226 | ||
| 227 | node->object = NULL; | 227 | node->object = NULL; |
| 228 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { | 228 | if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) { |
| 229 | |||
| 230 | /* Unlink object from front of possible object list */ | ||
| 231 | |||
| 229 | node->object = obj_desc->common.next_object; | 232 | node->object = obj_desc->common.next_object; |
| 233 | |||
| 234 | /* Handle possible 2-descriptor object */ | ||
| 235 | |||
| 230 | if (node->object && | 236 | if (node->object && |
| 231 | ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) { | 237 | (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) { |
| 232 | node->object = node->object->common.next_object; | 238 | node->object = node->object->common.next_object; |
| 233 | } | 239 | } |
| 234 | } | 240 | } |
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c index ed4cb8683310..a3516de213fa 100644 --- a/drivers/acpi/acpica/utdelete.c +++ b/drivers/acpi/acpica/utdelete.c | |||
| @@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
| 75 | union acpi_operand_object *handler_desc; | 75 | union acpi_operand_object *handler_desc; |
| 76 | union acpi_operand_object *second_desc; | 76 | union acpi_operand_object *second_desc; |
| 77 | union acpi_operand_object *next_desc; | 77 | union acpi_operand_object *next_desc; |
| 78 | union acpi_operand_object *start_desc; | ||
| 78 | union acpi_operand_object **last_obj_ptr; | 79 | union acpi_operand_object **last_obj_ptr; |
| 79 | 80 | ||
| 80 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); | 81 | ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); |
| @@ -235,10 +236,11 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
| 235 | if (handler_desc) { | 236 | if (handler_desc) { |
| 236 | next_desc = | 237 | next_desc = |
| 237 | handler_desc->address_space.region_list; | 238 | handler_desc->address_space.region_list; |
| 239 | start_desc = next_desc; | ||
| 238 | last_obj_ptr = | 240 | last_obj_ptr = |
| 239 | &handler_desc->address_space.region_list; | 241 | &handler_desc->address_space.region_list; |
| 240 | 242 | ||
| 241 | /* Remove the region object from the handler's list */ | 243 | /* Remove the region object from the handler list */ |
| 242 | 244 | ||
| 243 | while (next_desc) { | 245 | while (next_desc) { |
| 244 | if (next_desc == object) { | 246 | if (next_desc == object) { |
| @@ -247,10 +249,19 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object) | |||
| 247 | break; | 249 | break; |
| 248 | } | 250 | } |
| 249 | 251 | ||
| 250 | /* Walk the linked list of handler */ | 252 | /* Walk the linked list of handlers */ |
| 251 | 253 | ||
| 252 | last_obj_ptr = &next_desc->region.next; | 254 | last_obj_ptr = &next_desc->region.next; |
| 253 | next_desc = next_desc->region.next; | 255 | next_desc = next_desc->region.next; |
| 256 | |||
| 257 | /* Prevent infinite loop if list is corrupted */ | ||
| 258 | |||
| 259 | if (next_desc == start_desc) { | ||
| 260 | ACPI_ERROR((AE_INFO, | ||
| 261 | "Circular region list in address handler object %p", | ||
| 262 | handler_desc)); | ||
| 263 | return_VOID; | ||
| 264 | } | ||
| 254 | } | 265 | } |
| 255 | 266 | ||
| 256 | if (handler_desc->address_space.handler_flags & | 267 | if (handler_desc->address_space.handler_flags & |
