Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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/52d1da5d
Signed-off-by: Erik Kaneda <erik.kaneda@intel.com>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Erik Kaneda and committed by
Rafael J. Wysocki
32cf1a12 0766efdf

+4 -13
+4 -13
drivers/acpi/acpica/nsrepair2.c
··· 495 495 union acpi_operand_object **return_object_ptr) 496 496 { 497 497 union acpi_operand_object *return_object = *return_object_ptr; 498 - union acpi_operand_object *new_string; 499 - char *source; 500 498 char *dest; 499 + char *source; 501 500 502 501 ACPI_FUNCTION_NAME(ns_repair_HID); 503 502 ··· 517 518 return_ACPI_STATUS(AE_OK); 518 519 } 519 520 520 - /* It is simplest to always create a new string object */ 521 - 522 - new_string = acpi_ut_create_string_object(return_object->string.length); 523 - if (!new_string) { 524 - return_ACPI_STATUS(AE_NO_MEMORY); 525 - } 526 - 527 521 /* 528 522 * Remove a leading asterisk if present. For some unknown reason, there 529 523 * are many machines in the field that contains IDs like this. ··· 526 534 source = return_object->string.pointer; 527 535 if (*source == '*') { 528 536 source++; 529 - new_string->string.length--; 537 + return_object->string.length--; 530 538 531 539 ACPI_DEBUG_PRINT((ACPI_DB_REPAIR, 532 540 "%s: Removed invalid leading asterisk\n", ··· 541 549 * "NNNN####" where N is an uppercase letter or decimal digit, and 542 550 * # is a hex digit. 543 551 */ 544 - for (dest = new_string->string.pointer; *source; dest++, source++) { 552 + for (dest = return_object->string.pointer; *source; dest++, source++) { 545 553 *dest = (char)toupper((int)*source); 546 554 } 555 + return_object->string.pointer[return_object->string.length] = 0; 547 556 548 - acpi_ut_remove_reference(return_object); 549 - *return_object_ptr = new_string; 550 557 return_ACPI_STATUS(AE_OK); 551 558 } 552 559