[PATCH] of: overlay: fix device_node leak when attaching node to changeset fails

From: Selby Mashiki

Date: Sun Oct 25 2026 - 14:03:01 EST


In add_changeset_node(), when creating a new target child node via
__of_node_dup(), tchild is initialized with a reference count of 1. If
of_changeset_attach_node() subsequently fails, add_changeset_node()
returns the error without calling of_node_put(tchild), leaking the
allocated device_node.

Furthermore, because OF_OVERLAY is set on tchild before
of_changeset_attach_node() is called, calling of_node_put(tchild) when
tchild was never added to the changeset (and thus never had
OF_OVERLAY_FREE_CSET set by __of_changeset_entry_destroy()) would cause
of_node_release() to log a premature refcount zero error and skip
freeing the node.

Move of_node_set_flag(tchild, OF_OVERLAY) after
of_changeset_attach_node() succeeds and call of_node_put(tchild) on the
failure path, matching of_changeset_create_node().

Fixes: 7c528e457d53 ("of: overlay: add missing of_node_put() after add new node to changeset")
Fixes: 144552c78692 ("of: overlay: add tests to validate kfrees from overlay removal")
Signed-off-by: Selby Mashiki <mashikiselby@xxxxxxxxx>
---
drivers/of/overlay.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 08d535174..936d5d742 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -442,11 +442,13 @@ static int add_changeset_node(struct overlay_changeset *ovcs,
if (phandle && (size == 4))
tchild->phandle = be32_to_cpup(phandle);

- of_node_set_flag(tchild, OF_OVERLAY);
-
ret = of_changeset_attach_node(&ovcs->cset, tchild);
- if (ret)
+ if (ret) {
+ of_node_put(tchild);
return ret;
+ }
+
+ of_node_set_flag(tchild, OF_OVERLAY);

target_child.np = tchild;
target_child.in_livetree = false;
--
2.56.0