diff options
author | Bob Moore <robert.moore@intel.com> | 2013-03-08 04:19:38 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-03-11 19:45:03 -0400 |
commit | c13085e519e8984fede41fa3d6a5502523b10996 (patch) | |
tree | c993b660f58d41ab46b93c4a810517de6f9ab072 /drivers/acpi/acpica | |
parent | f6161aa153581da4a3867a2d1a7caf4be19b6ec9 (diff) |
ACPICA: Resource Mgr: Prevent infinite loops in resource walks
Add checks for zero-length resource descriptors in all code that
loops through a resource descriptor list. This prevents possible
infinite loops because the length is used to increment the traveral
pointer and detect the end-of-descriptor.
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')
-rw-r--r-- | drivers/acpi/acpica/rscalc.c | 6 | ||||
-rw-r--r-- | drivers/acpi/acpica/rsdump.c | 8 | ||||
-rw-r--r-- | drivers/acpi/acpica/rslist.c | 8 | ||||
-rw-r--r-- | drivers/acpi/acpica/rsxface.c | 8 |
4 files changed, 29 insertions, 1 deletions
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index 7816d4eef04e..72077fa1eea5 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
@@ -202,6 +202,12 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) | |||
202 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); | 202 | return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE); |
203 | } | 203 | } |
204 | 204 | ||
205 | /* Sanity check the length. It must not be zero, or we loop forever */ | ||
206 | |||
207 | if (!resource->length) { | ||
208 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
209 | } | ||
210 | |||
205 | /* Get the base size of the (external stream) resource descriptor */ | 211 | /* Get the base size of the (external stream) resource descriptor */ |
206 | 212 | ||
207 | total_size = acpi_gbl_aml_resource_sizes[resource->type]; | 213 | total_size = acpi_gbl_aml_resource_sizes[resource->type]; |
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c index cab51445189d..b5fc0db2e87b 100644 --- a/drivers/acpi/acpica/rsdump.c +++ b/drivers/acpi/acpica/rsdump.c | |||
@@ -385,6 +385,14 @@ void acpi_rs_dump_resource_list(struct acpi_resource *resource_list) | |||
385 | return; | 385 | return; |
386 | } | 386 | } |
387 | 387 | ||
388 | /* Sanity check the length. It must not be zero, or we loop forever */ | ||
389 | |||
390 | if (!resource_list->length) { | ||
391 | acpi_os_printf | ||
392 | ("Invalid zero length descriptor in resource list\n"); | ||
393 | return; | ||
394 | } | ||
395 | |||
388 | /* Dump the resource descriptor */ | 396 | /* Dump the resource descriptor */ |
389 | 397 | ||
390 | if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { | 398 | if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { |
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c index ee2e206fc6c8..6053aa182093 100644 --- a/drivers/acpi/acpica/rslist.c +++ b/drivers/acpi/acpica/rslist.c | |||
@@ -178,6 +178,14 @@ acpi_rs_convert_resources_to_aml(struct acpi_resource *resource, | |||
178 | return_ACPI_STATUS(AE_BAD_DATA); | 178 | return_ACPI_STATUS(AE_BAD_DATA); |
179 | } | 179 | } |
180 | 180 | ||
181 | /* Sanity check the length. It must not be zero, or we loop forever */ | ||
182 | |||
183 | if (!resource->length) { | ||
184 | ACPI_ERROR((AE_INFO, | ||
185 | "Invalid zero length descriptor in resource list\n")); | ||
186 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
187 | } | ||
188 | |||
181 | /* Perform the conversion */ | 189 | /* Perform the conversion */ |
182 | 190 | ||
183 | if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { | 191 | if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { |
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c index 15d6eaef0e28..c0e5d2d3ce67 100644 --- a/drivers/acpi/acpica/rsxface.c +++ b/drivers/acpi/acpica/rsxface.c | |||
@@ -563,13 +563,19 @@ acpi_walk_resource_buffer(struct acpi_buffer * buffer, | |||
563 | 563 | ||
564 | while (resource < resource_end) { | 564 | while (resource < resource_end) { |
565 | 565 | ||
566 | /* Sanity check the resource */ | 566 | /* Sanity check the resource type */ |
567 | 567 | ||
568 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { | 568 | if (resource->type > ACPI_RESOURCE_TYPE_MAX) { |
569 | status = AE_AML_INVALID_RESOURCE_TYPE; | 569 | status = AE_AML_INVALID_RESOURCE_TYPE; |
570 | break; | 570 | break; |
571 | } | 571 | } |
572 | 572 | ||
573 | /* Sanity check the length. It must not be zero, or we loop forever */ | ||
574 | |||
575 | if (!resource->length) { | ||
576 | return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH); | ||
577 | } | ||
578 | |||
573 | /* Invoke the user function, abort on any error returned */ | 579 | /* Invoke the user function, abort on any error returned */ |
574 | 580 | ||
575 | status = user_function(resource, context); | 581 | status = user_function(resource, context); |