diff options
| author | Lin Ming <ming.m.lin@intel.com> | 2008-09-26 23:28:46 -0400 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2008-10-22 23:14:47 -0400 |
| commit | c35def2118d3d7cceb0f69d6707f613a7473df15 (patch) | |
| tree | eef4fcd1850ebd28dff173d89d4dd06efcbd8bec /drivers/acpi/parser | |
| parent | bbbbeb8e31af97f11b84294b2e7e5607125829d2 (diff) | |
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>
Diffstat (limited to 'drivers/acpi/parser')
| -rw-r--r-- | drivers/acpi/parser/psparse.c | 28 |
1 files changed, 11 insertions, 17 deletions
diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 15e1702e48d6..52caaf6582e7 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c | |||
| @@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
| 137 | union acpi_parse_object *next; | 137 | union acpi_parse_object *next; |
| 138 | const struct acpi_opcode_info *parent_info; | 138 | const struct acpi_opcode_info *parent_info; |
| 139 | union acpi_parse_object *replacement_op = NULL; | 139 | union acpi_parse_object *replacement_op = NULL; |
| 140 | acpi_status status = AE_OK; | ||
| 140 | 141 | ||
| 141 | ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op); | 142 | ACPI_FUNCTION_TRACE_PTR(ps_complete_this_op, op); |
| 142 | 143 | ||
| @@ -186,7 +187,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
| 186 | replacement_op = | 187 | replacement_op = |
| 187 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 188 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
| 188 | if (!replacement_op) { | 189 | if (!replacement_op) { |
| 189 | goto allocate_error; | 190 | status = AE_NO_MEMORY; |
| 190 | } | 191 | } |
| 191 | break; | 192 | break; |
| 192 | 193 | ||
| @@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
| 211 | replacement_op = | 212 | replacement_op = |
| 212 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 213 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
| 213 | if (!replacement_op) { | 214 | if (!replacement_op) { |
| 214 | goto allocate_error; | 215 | status = AE_NO_MEMORY; |
| 215 | } | 216 | } |
| 216 | } else | 217 | } else |
| 217 | if ((op->common.parent->common.aml_opcode == | 218 | if ((op->common.parent->common.aml_opcode == |
| @@ -226,13 +227,13 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
| 226 | acpi_ps_alloc_op(op->common. | 227 | acpi_ps_alloc_op(op->common. |
| 227 | aml_opcode); | 228 | aml_opcode); |
| 228 | if (!replacement_op) { | 229 | if (!replacement_op) { |
| 229 | goto allocate_error; | 230 | status = AE_NO_MEMORY; |
| 231 | } else { | ||
| 232 | replacement_op->named.data = | ||
| 233 | op->named.data; | ||
| 234 | replacement_op->named.length = | ||
| 235 | op->named.length; | ||
| 230 | } | 236 | } |
| 231 | |||
| 232 | replacement_op->named.data = | ||
| 233 | op->named.data; | ||
| 234 | replacement_op->named.length = | ||
| 235 | op->named.length; | ||
| 236 | } | 237 | } |
| 237 | } | 238 | } |
| 238 | break; | 239 | break; |
| @@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
| 242 | replacement_op = | 243 | replacement_op = |
| 243 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); | 244 | acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP); |
| 244 | if (!replacement_op) { | 245 | if (!replacement_op) { |
| 245 | goto allocate_error; | 246 | status = AE_NO_MEMORY; |
| 246 | } | 247 | } |
| 247 | } | 248 | } |
| 248 | 249 | ||
| @@ -302,14 +303,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state, | |||
| 302 | /* Now we can actually delete the subtree rooted at Op */ | 303 | /* Now we can actually delete the subtree rooted at Op */ |
| 303 | 304 | ||
| 304 | acpi_ps_delete_parse_tree(op); | 305 | acpi_ps_delete_parse_tree(op); |
| 305 | return_ACPI_STATUS(AE_OK); | 306 | return_ACPI_STATUS(status); |
| 306 | |||
| 307 | allocate_error: | ||
| 308 | |||
| 309 | /* Always delete the subtree, even on error */ | ||
| 310 | |||
| 311 | acpi_ps_delete_parse_tree(op); | ||
| 312 | return_ACPI_STATUS(AE_NO_MEMORY); | ||
| 313 | } | 307 | } |
| 314 | 308 | ||
| 315 | /******************************************************************************* | 309 | /******************************************************************************* |
