Commit c35def21 authored by Lin Ming's avatar Lin Ming Committed by Len Brown

ACPICA: Fix fault after mem allocation failure in AML parser

Fixes a crash if a memory allocation fails during the Op completion
routine acpi_ps_complete_this_op().

http://www.acpica.org/bugzilla/show_bug.cgi?id=492Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent bbbbeb8e
...@@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, ...@@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
union acpi_parse_object *next; union acpi_parse_object *next;
const struct acpi_opcode_info *parent_info; const struct acpi_opcode_info *parent_info;
union acpi_parse_object *replacement_op = NULL; union acpi_parse_object *replacement_op = NULL;
acpi_status status = AE_OK;
ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op); ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op);
...@@ -186,7 +187,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, ...@@ -186,7 +187,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
replacement_op = replacement_op =
acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
if (!replacement_op) { if (!replacement_op) {
goto allocate_error; status = AE_NO_MEMORY;
} }
break; break;
...@@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, ...@@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
replacement_op = replacement_op =
acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
if (!replacement_op) { if (!replacement_op) {
goto allocate_error; status = AE_NO_MEMORY;
} }
} else } else
if ((op->common.parent->common.aml_opcode == if ((op->common.parent->common.aml_opcode ==
...@@ -226,15 +227,15 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, ...@@ -226,15 +227,15 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
acpi_ps_alloc_op(op->common. acpi_ps_alloc_op(op->common.
aml_opcode); aml_opcode);
if (!replacement_op) { if (!replacement_op) {
goto allocate_error; status = AE_NO_MEMORY;
} } else {
replacement_op->named.data = replacement_op->named.data =
op->named.data; op->named.data;
replacement_op->named.length = replacement_op->named.length =
op->named.length; op->named.length;
} }
} }
}
break; break;
default: default:
...@@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, ...@@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
replacement_op = replacement_op =
acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
if (!replacement_op) { if (!replacement_op) {
goto allocate_error; status = AE_NO_MEMORY;
} }
} }
...@@ -302,14 +303,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, ...@@ -302,14 +303,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
/* Now we can actually delete the subtree rooted at Op */ /* Now we can actually delete the subtree rooted at Op */
acpi_ps_delete_parse_tree(op); acpi_ps_delete_parse_tree(op);
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(status);
allocate_error:
/* Always delete the subtree, even on error */
acpi_ps_delete_parse_tree(op);
return_ACPI_STATUS(AE_NO_MEMORY);
} }
/******************************************************************************* /*******************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment