mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind
@ 2026-10-15  1:28 Iurii Trukhin
  2026-10-15 15:58 ` Markus Elfring
  2026-10-15 16:04 ` Rafael J. Wysocki (Intel)
  0 siblings, 2 replies; 3+ messages in thread
From: Iurii Trukhin @ 2026-10-15  1:28 UTC (permalink / raw)
  To: Rafael J. Wysocki, Len Brown
  Cc: Robert Moore, Erik Kaneda, Maciej Wieczor-Retman,
	Pawel Chmielewski, linux-acpi, acpica-devel, linux-kernel,
	Iurii Trukhin

acpi_ps_complete_this_op() decides whether to defer deletion of an
AML_CLASS_ARGUMENT parse object to its enclosing parent by checking
walk_state->op_info->class instead of the opcode class of the op being
completed.

When acpi_ps_complete_op() or acpi_ps_complete_final_op() unwinds open
parser scopes on AE_CTRL_TERMINATE or an execution error (such as
AE_NOT_FOUND when resolving a missing symbol inside a control method),
it pops each enclosing parent op and passes it to
acpi_ps_complete_this_op() while walk_state->op_info still points to the
last child op that failed. If that failing child op was of class
AML_CLASS_ARGUMENT (for example, AML_INT_NAMEPATH_OP when
acpi_ps_get_arguments() fails to resolve a method call or predicate
operand), acpi_ps_complete_this_op() sees AML_CLASS_ARGUMENT for every
popped parent op and returns AE_OK early without deleting any of the
enclosing parent subtrees.

For nested control methods invoked via acpi_ds_call_control_method(),
the walk state is initialized with root_op = NULL, so top-level ops in
the called method (such as AML_IF_OP) have op->common.parent == NULL
and are never attached to a root scope op. Skipping
acpi_ps_delete_parse_tree() during error unwind leaks the entire parse
subtree (both Acpi-ParseExt and Acpi-Parse objects, the latter merged
by SLUB into the 80-byte Acpi-State kmem_cache on 64-bit kernels) on
every failed GPE or method evaluation.

Look up the opcode info of op->common.aml_opcode directly in
acpi_ps_complete_this_op() and only defer deletion of
AML_CLASS_ARGUMENT ops when op->common.parent is non-NULL, without
mutating walk_state->opcode during error unwind (which acpi_ps_parse_loop()
still inspects when skipping failed module-level scopes). Remove the
now-redundant acpi_ps_delete_parse_tree(*op) inside the AML_REGION_OP /
AML_DATA_REGION_OP error block in acpi_ps_complete_op(), which previously
worked around this bug only for region ops and caused a double-free when
region creation failed on a non-argument child op. Also use
acpi_ut_delete_generic_state() instead of ACPI_FREE() when draining
walk_state->control_state in acpi_ps_parse_loop().

Fixes: 5088814a6e93 ("ACPICA: AML parser: attempt to continue loading
table after error")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221241
Signed-off-by: Iurii Trukhin <yuri@trukhin.com>
---
 drivers/acpi/acpica/psloop.c   | 5 +++--
 drivers/acpi/acpica/psobject.c | 1 -
 drivers/acpi/acpica/psparse.c  | 7 +++++--
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index 24a57f971c96..0b672a531907 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -464,8 +464,9 @@ acpi_status acpi_ps_parse_loop(struct
acpi_walk_state *walk_state)
 						walk_state->aml =
 						    parser_state->aml;
 					}
-					ACPI_FREE(acpi_ut_pop_generic_state
-						  (&walk_state->control_state));
+					acpi_ut_delete_generic_state
+					    (acpi_ut_pop_generic_state
+					     (&walk_state->control_state));
 				}
 				op = NULL;
 				continue;
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
index 629cafab1930..f1425b98087b 100644
--- a/drivers/acpi/acpica/psobject.c
+++ b/drivers/acpi/acpica/psobject.c
@@ -559,7 +559,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
 								node);
 					acpi_ns_remove_node((*op)->common.node);
 					(*op)->common.node = NULL;
-					acpi_ps_delete_parse_tree(*op);
 				}

 				status2 =
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
index 42ec8abef626..b5110d43ab7a 100644
--- a/drivers/acpi/acpica/psparse.c
+++ b/drivers/acpi/acpica/psparse.c
@@ -108,6 +108,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state *walk_state,
 {
 	union acpi_parse_object *prev;
 	union acpi_parse_object *next;
+	const struct acpi_opcode_info *op_info;
 	const struct acpi_opcode_info *parent_info;
 	union acpi_parse_object *replacement_op = NULL;
 	acpi_status status = AE_OK;
@@ -124,9 +125,11 @@ acpi_ps_complete_this_op(struct acpi_walk_state
*walk_state,

 	/* Delete this op and the subtree below it if asked to */

+	op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
 	if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) !=
-	     ACPI_PARSE_DELETE_TREE)
-	    || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
+	     ACPI_PARSE_DELETE_TREE) ||
+	    ((op_info->class == AML_CLASS_ARGUMENT) &&
+	     op->common.parent)) {
 		return_ACPI_STATUS(AE_OK);
 	}

-- 
2.56.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-15 16:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-15  1:28 [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind Iurii Trukhin
2026-10-15 15:58 ` Markus Elfring
2026-10-15 16:04 ` Rafael J. Wysocki (Intel)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®