ACPICA: Fix fault after mem allocation failure in AML parser
authorLin Ming <ming.m.lin@intel.com>
Sat, 27 Sep 2008 03:28:46 +0000 (11:28 +0800)
committerLen Brown <len.brown@intel.com>
Thu, 23 Oct 2008 03:14:47 +0000 (23:14 -0400)
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>
drivers/acpi/parser/psparse.c

index 15e1702..52caaf6 100644 (file)
@@ -137,6 +137,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
        union acpi_parse_object *next;
        const struct acpi_opcode_info *parent_info;
        union acpi_parse_object *replacement_op = NULL;
+       acpi_status status = AE_OK;
 
        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 =
                            acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
                        if (!replacement_op) {
-                               goto allocate_error;
+                               status = AE_NO_MEMORY;
                        }
                        break;
 
@@ -211,7 +212,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                                replacement_op =
                                    acpi_ps_alloc_op(AML_INT_RETURN_VALUE_OP);
                                if (!replacement_op) {
-                                       goto allocate_error;
+                                       status = AE_NO_MEMORY;
                                }
                        } else
                            if ((op->common.parent->common.aml_opcode ==
@@ -226,13 +227,13 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                                            acpi_ps_alloc_op(op->common.
                                                             aml_opcode);
                                        if (!replacement_op) {
-                                               goto allocate_error;
+                                               status = AE_NO_MEMORY;
+                                       } else {
+                                               replacement_op->named.data =
+                                                   op->named.data;
+                                               replacement_op->named.length =
+                                                   op->named.length;
                                        }
-
-                                       replacement_op->named.data =
-                                           op->named.data;
-                                       replacement_op->named.length =
-                                           op->named.length;
                                }
                        }
                        break;
@@ -242,7 +243,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                        replacement_op =
                            acpi_ps_alloc_op(AML_INT_RETURN_VALUE_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 */
 
        acpi_ps_delete_parse_tree(op);
-       return_ACPI_STATUS(AE_OK);
-
-      allocate_error:
-
-       /* Always delete the subtree, even on error */
-
-       acpi_ps_delete_parse_tree(op);
-       return_ACPI_STATUS(AE_NO_MEMORY);
+       return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************