Commit 32cf1a12 authored by Erik Kaneda's avatar Erik Kaneda Committed by Rafael J. Wysocki

ACPICA: Interpreter: fix memory leak by using existing buffer

ACPICA commit 52d1da5dcbd79a722b70f02a1a83f04088f51ff6

There was a memory leak that ocurred when a _CID object is defined as
a package containing string objects. When _CID is checked for any
possible repairs, it calls a helper function to repair _HID (because
_CID basically contains multiple _HID entries).

The _HID repair function assumes that string objects are standalone
objects that are not contained inside of any packages. The _HID
repair function replaces the string object with a brand new object
and attempts to delete the old object by decrementing the reference
count of the old object. Strings inside of packages have a reference
count of 2 so the _HID repair function leaves this object in a
dangling state and causes a memory leak.

Instead of allocating a brand new object and removing the old object,
use the existing object when repairing the _HID object.

Link: https://github.com/acpica/acpica/commit/52d1da5dSigned-off-by: default avatarErik Kaneda <erik.kaneda@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 0766efdf
...@@ -495,9 +495,8 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, ...@@ -495,9 +495,8 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info,
union acpi_operand_object **return_object_ptr) union acpi_operand_object **return_object_ptr)
{ {
union acpi_operand_object *return_object = *return_object_ptr; union acpi_operand_object *return_object = *return_object_ptr;
union acpi_operand_object *new_string;
char *source;
char *dest; char *dest;
char *source;
ACPI_FUNCTION_NAME(ns_repair_HID); ACPI_FUNCTION_NAME(ns_repair_HID);
...@@ -518,13 +517,6 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, ...@@ -518,13 +517,6 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info,
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
/* It is simplest to always create a new string object */
new_string = acpi_ut_create_string_object(return_object->string.length);
if (!new_string) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* /*
* Remove a leading asterisk if present. For some unknown reason, there * Remove a leading asterisk if present. For some unknown reason, there
* are many machines in the field that contains IDs like this. * are many machines in the field that contains IDs like this.
...@@ -534,7 +526,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, ...@@ -534,7 +526,7 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info,
source = return_object->string.pointer; source = return_object->string.pointer;
if (*source == '*') { if (*source == '*') {
source++; source++;
new_string->string.length--; return_object->string.length--;
ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
"%s: Removed invalid leading asterisk\n", "%s: Removed invalid leading asterisk\n",
...@@ -549,12 +541,11 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info, ...@@ -549,12 +541,11 @@ acpi_ns_repair_HID(struct acpi_evaluate_info *info,
* "NNNN####" where N is an uppercase letter or decimal digit, and * "NNNN####" where N is an uppercase letter or decimal digit, and
* # is a hex digit. * # is a hex digit.
*/ */
for (dest = new_string->string.pointer; *source; dest++, source++) { for (dest = return_object->string.pointer; *source; dest++, source++) {
*dest = (char)toupper((int)*source); *dest = (char)toupper((int)*source);
} }
return_object->string.pointer[return_object->string.length] = 0;
acpi_ut_remove_reference(return_object);
*return_object_ptr = new_string;
return_ACPI_STATUS(AE_OK); return_ACPI_STATUS(AE_OK);
} }
......
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