summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobert Moore <Robert.Moore@intel.com>2017-10-05 09:04:50 -0700
committerRobert Moore <Robert.Moore@intel.com>2017-10-05 09:04:50 -0700
commitea593f62d0aff7248c6c1a29548a13fd30307a78 (patch)
tree2f744a7e72f7a290ee17f615701de835b446d27d /source
parentf230f4df26d07b97ef00be39156ecee64250447d (diff)
downloadacpica-ea593f62d0aff7248c6c1a29548a13fd30307a78.tar.gz
Fix repair code for possible memory leak on package elements
If a package element requires repair with a new object, the original element can possibly be not deleted, leading to a memory leak. Fixes ACPICA BZ 1392, which is one example of the problem.
Diffstat (limited to 'source')
-rw-r--r--source/components/namespace/nsrepair.c9
-rw-r--r--source/components/namespace/nsrepair2.c7
-rw-r--r--source/components/utilities/utdelete.c10
-rw-r--r--source/include/acutils.h1
4 files changed, 23 insertions, 4 deletions
diff --git a/source/components/namespace/nsrepair.c b/source/components/namespace/nsrepair.c
index 144db2b38..019db5097 100644
--- a/source/components/namespace/nsrepair.c
+++ b/source/components/namespace/nsrepair.c
@@ -431,9 +431,12 @@ ObjectRepaired:
AcpiUtGetObjectTypeName (NewObject)));
}
- /* Delete old object, install the new return object */
-
- AcpiUtRemoveReference (ReturnObject);
+ /*
+ * Force-delete the original object, then install the new return object.
+ * Note: Can delete the original because the method has exited and the
+ * Locals and Arguments are gone.
+ */
+ AcpiUtUpdateObjectReference (ReturnObject, REF_FORCE_DELETE);
*ReturnObjectPtr = NewObject;
Info->ReturnFlags |= ACPI_OBJECT_REPAIRED;
return (AE_OK);
diff --git a/source/components/namespace/nsrepair2.c b/source/components/namespace/nsrepair2.c
index 18d3b091b..a93103382 100644
--- a/source/components/namespace/nsrepair2.c
+++ b/source/components/namespace/nsrepair2.c
@@ -751,7 +751,12 @@ AcpiNsRepair_HID (
*Dest = (char) toupper ((int) *Source);
}
- AcpiUtRemoveReference (ReturnObject);
+ /*
+ * Force-delete the original object, install the new return object.
+ * Note: Can delete the original because the method has exited and the
+ * Locals and Arguments are gone.
+ */
+ AcpiUtUpdateObjectReference (ReturnObject, REF_FORCE_DELETE);
*ReturnObjectPtr = NewString;
return (AE_OK);
}
diff --git a/source/components/utilities/utdelete.c b/source/components/utilities/utdelete.c
index ac9e73da0..c0010eb74 100644
--- a/source/components/utilities/utdelete.c
+++ b/source/components/utilities/utdelete.c
@@ -593,6 +593,16 @@ AcpiUtUpdateRefCount (
}
break;
+ case REF_FORCE_DELETE:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS,
+ "Obj %p Force delete! (Set to 0)\n", Object));
+
+ Object->Common.ReferenceCount = 1;
+ AcpiUtDeleteInternalObj (Object);
+ AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
+ return;
+
default:
AcpiOsReleaseLock (AcpiGbl_ReferenceCountLock, LockFlags);
diff --git a/source/include/acutils.h b/source/include/acutils.h
index a3f0150b4..0a645508f 100644
--- a/source/include/acutils.h
+++ b/source/include/acutils.h
@@ -290,6 +290,7 @@ typedef struct acpi_pkg_info
#define REF_INCREMENT (UINT16) 0
#define REF_DECREMENT (UINT16) 1
+#define REF_FORCE_DELETE (UINT16) 2
/* AcpiUtDumpBuffer */