ACPICA: Fix memory leak for ill-formed Package objects

Fixes a possible memory leak in the interpreter for package
objects if the package initializer list is longer than the
defined size of the package. This apparently can only happen
if the BIOS changes the package size on the fly (seen in a _PSS
object), as both iASL and the other compiler do not allow this.
The interpreter will truncate the package to the defined size
(and issue an error message), but can leave the extra objects
undeleted if they have been pre-created during the argument
processing (such is the case if the package consists of a number
of sub-packages as in the _PSS.) ACPICA BZ 805.

http://www.acpica.org/bugzilla/show_bug.cgi?id=805

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Bob Moore 2009-09-03 10:03:37 +08:00 committed by Len Brown
parent e678902ee8
commit e3fe0913b8

View File

@ -482,14 +482,27 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
if (arg) {
/*
* num_elements was exhausted, but there are remaining elements in the
* package_list.
* package_list. Truncate the package to num_elements.
*
* Note: technically, this is an error, from ACPI spec: "It is an error
* for NumElements to be less than the number of elements in the
* PackageList". However, for now, we just print an error message and
* no exception is returned.
* PackageList". However, we just print an error message and
* no exception is returned. This provides Windows compatibility. Some
* BIOSs will alter the num_elements on the fly, creating this type
* of ill-formed package object.
*/
while (arg) {
/*
* We must delete any package elements that were created earlier
* and are not going to be used because of the package truncation.
*/
if (arg->common.node) {
acpi_ut_remove_reference(ACPI_CAST_PTR
(union
acpi_operand_object,
arg->common.node));
arg->common.node = NULL;
}
/* Find out how many elements there really are */
@ -498,7 +511,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
}
ACPI_WARNING((AE_INFO,
"Package List length (%X) larger than NumElements count (%X), truncated\n",
"Package List length (0x%X) larger than NumElements count (0x%X), truncated\n",
i, element_count));
} else if (i < element_count) {
/*
@ -506,7 +519,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state,
* Note: this is not an error, the package is padded out with NULLs.
*/
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Package List length (%X) smaller than NumElements count (%X), padded with null elements\n",
"Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n",
i, element_count));
}