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=492

Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Lin Ming 2008-09-27 11:28:46 +08:00 committed by Len Brown
parent bbbbeb8e31
commit c35def2118

View File

@ -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,
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,
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,
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,
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,
/* 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);
} }
/******************************************************************************* /*******************************************************************************