summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Wolf <W_Armin@gmx.de>2024-04-14 21:50:33 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2024-08-29 19:03:14 +0200
commite6169a8ffee8a012badd8c703716e761ce851b15 (patch)
tree98bdda476f62adb7dd365ed796cc759fa328e5f5
parent5accb265f7a1b23e52b0ec42313d1e12895552f4 (diff)
downloadlinux-e6169a8ffee8a012badd8c703716e761ce851b15.tar.gz
linux-e6169a8ffee8a012badd8c703716e761ce851b15.tar.bz2
linux-e6169a8ffee8a012badd8c703716e761ce851b15.zip
ACPICA: Fix memory leak if acpi_ps_get_next_field() fails
ACPICA commit 1280045754264841b119a5ede96cd005bc09b5a7 If acpi_ps_get_next_field() fails, the previously created field list needs to be properly disposed before returning the status code. Link: https://github.com/acpica/acpica/commit/12800457 Signed-off-by: Armin Wolf <W_Armin@gmx.de> [ rjw: Rename local variable to avoid compiler confusion ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/psargs.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c
index 7debfd5ce0d8..28582adfc0ac 100644
--- a/drivers/acpi/acpica/psargs.c
+++ b/drivers/acpi/acpica/psargs.c
@@ -25,6 +25,8 @@ acpi_ps_get_next_package_length(struct acpi_parse_state *parser_state);
static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
*parser_state);
+static void acpi_ps_free_field_list(union acpi_parse_object *start);
+
/*******************************************************************************
*
* FUNCTION: acpi_ps_get_next_package_length
@@ -685,6 +687,39 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
/*******************************************************************************
*
+ * FUNCTION: acpi_ps_free_field_list
+ *
+ * PARAMETERS: start - First Op in field list
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Free all Op objects inside a field list.
+ *
+ ******************************************************************************/
+
+static void acpi_ps_free_field_list(union acpi_parse_object *start)
+{
+ union acpi_parse_object *cur = start;
+ union acpi_parse_object *next;
+ union acpi_parse_object *arg;
+
+ while (cur) {
+ next = cur->common.next;
+
+ /* AML_INT_CONNECTION_OP can have a single argument */
+
+ arg = acpi_ps_get_arg(cur, 0);
+ if (arg) {
+ acpi_ps_free_op(arg);
+ }
+
+ acpi_ps_free_op(cur);
+ cur = next;
+ }
+}
+
+/*******************************************************************************
+ *
* FUNCTION: acpi_ps_get_next_arg
*
* PARAMETERS: walk_state - Current state
@@ -751,6 +786,10 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state,
while (parser_state->aml < parser_state->pkg_end) {
field = acpi_ps_get_next_field(parser_state);
if (!field) {
+ if (arg) {
+ acpi_ps_free_field_list(arg);
+ }
+
return_ACPI_STATUS(AE_NO_MEMORY);
}