summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/acpica/dsopcode.c
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2015-08-25 04:28:39 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-08-25 23:11:31 +0200
commit9f41fd8a175ff87ba610fc387a6922b0f49f8e19 (patch)
tree3cb91631143c9e10a9b7e3f22c02e59a0aa72833 /drivers/acpi/acpica/dsopcode.c
parentACPICA: Disassembler: Remove duplicate code in _PLD processing. (diff)
downloadlinux-9f41fd8a175ff87ba610fc387a6922b0f49f8e19.tar.xz
linux-9f41fd8a175ff87ba610fc387a6922b0f49f8e19.zip
ACPICA: Update parameter validation for data_table_region and load_table
ACPICA commit 51ab555e60b4a3de3cc4a846e86d0de255be441a Add additional validation for the table signature and the OEM strings. Eliminates buffer read overrun in data_table_region. ACPICA BZ 1184. Link: https://bugs.acpica.org/show_bug.cgi?id=1184 Link: https://github.com/acpica/acpica/commit/51ab555e 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/dsopcode.c')
-rw-r--r--drivers/acpi/acpica/dsopcode.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index ea0cc4e08f80..81d7b9863e32 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -480,8 +480,8 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
union acpi_operand_object **operand;
struct acpi_namespace_node *node;
union acpi_parse_object *next_op;
- u32 table_index;
struct acpi_table_header *table;
+ u32 table_index;
ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
@@ -504,6 +504,8 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}
+ operand = &walk_state->operands[0];
+
/*
* Resolve the Signature string, oem_id string,
* and oem_table_id string operands
@@ -511,32 +513,34 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
status = acpi_ex_resolve_operands(op->common.aml_opcode,
ACPI_WALK_OPERANDS, walk_state);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto cleanup;
}
- operand = &walk_state->operands[0];
-
/* Find the ACPI table */
status = acpi_tb_find_table(operand[0]->string.pointer,
operand[1]->string.pointer,
operand[2]->string.pointer, &table_index);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ if (status == AE_NOT_FOUND) {
+ ACPI_ERROR((AE_INFO,
+ "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
+ operand[0]->string.pointer,
+ operand[1]->string.pointer,
+ operand[2]->string.pointer));
+ }
+ goto cleanup;
}
- acpi_ut_remove_reference(operand[0]);
- acpi_ut_remove_reference(operand[1]);
- acpi_ut_remove_reference(operand[2]);
-
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto cleanup;
}
obj_desc = acpi_ns_get_attached_object(node);
if (!obj_desc) {
- return_ACPI_STATUS(AE_NOT_EXIST);
+ status = AE_NOT_EXIST;
+ goto cleanup;
}
obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
@@ -551,6 +555,11 @@ acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
obj_desc->region.flags |= AOPOBJ_DATA_VALID;
+cleanup:
+ acpi_ut_remove_reference(operand[0]);
+ acpi_ut_remove_reference(operand[1]);
+ acpi_ut_remove_reference(operand[2]);
+
return_ACPI_STATUS(status);
}