summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2013-03-08 09:19:38 +0000
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-03-12 00:45:03 +0100
commitc13085e519e8984fede41fa3d6a5502523b10996 (patch)
treec993b660f58d41ab46b93c4a810517de6f9ab072
parentf6161aa153581da4a3867a2d1a7caf4be19b6ec9 (diff)
downloadlinux-3.10-c13085e519e8984fede41fa3d6a5502523b10996.tar.gz
linux-3.10-c13085e519e8984fede41fa3d6a5502523b10996.tar.bz2
linux-3.10-c13085e519e8984fede41fa3d6a5502523b10996.zip
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>
-rw-r--r--drivers/acpi/acpica/rscalc.c6
-rw-r--r--drivers/acpi/acpica/rsdump.c8
-rw-r--r--drivers/acpi/acpica/rslist.c8
-rw-r--r--drivers/acpi/acpica/rsxface.c8
4 files changed, 29 insertions, 1 deletions
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 7816d4eef04..72077fa1eea 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)
return_ACPI_STATUS(AE_AML_INVALID_RESOURCE_TYPE);
}
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!resource->length) {
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
+ }
+
/* Get the base size of the (external stream) resource descriptor */
total_size = acpi_gbl_aml_resource_sizes[resource->type];
diff --git a/drivers/acpi/acpica/rsdump.c b/drivers/acpi/acpica/rsdump.c
index cab51445189..b5fc0db2e87 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)
return;
}
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!resource_list->length) {
+ acpi_os_printf
+ ("Invalid zero length descriptor in resource list\n");
+ return;
+ }
+
/* Dump the resource descriptor */
if (type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
diff --git a/drivers/acpi/acpica/rslist.c b/drivers/acpi/acpica/rslist.c
index ee2e206fc6c..6053aa18209 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,
return_ACPI_STATUS(AE_BAD_DATA);
}
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!resource->length) {
+ ACPI_ERROR((AE_INFO,
+ "Invalid zero length descriptor in resource list\n"));
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
+ }
+
/* Perform the conversion */
if (resource->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c
index 15d6eaef0e2..c0e5d2d3ce6 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,
while (resource < resource_end) {
- /* Sanity check the resource */
+ /* Sanity check the resource type */
if (resource->type > ACPI_RESOURCE_TYPE_MAX) {
status = AE_AML_INVALID_RESOURCE_TYPE;
break;
}
+ /* Sanity check the length. It must not be zero, or we loop forever */
+
+ if (!resource->length) {
+ return_ACPI_STATUS(AE_AML_BAD_RESOURCE_LENGTH);
+ }
+
/* Invoke the user function, abort on any error returned */
status = user_function(resource, context);