[PATCH RFC 3/4] of/overlay: rewrite /aliases path values to live-tree paths
From: Abdurrahman Hussain
Date: Mon Jul 20 2026 - 22:53:18 EST
/aliases entries added by an overlay reference labeled nodes inside
the overlay via '&label' in the .dtso. dtc renders those references
as string paths at compile time, but the paths encode the overlay's
internal fragment layout (e.g. "/fragment@1/__overlay__/fpga@0/i2c@40000")
rather than the location where the node will live after apply.
Currently only /__symbols__ has its property values rewritten from
overlay-internal paths to live-tree paths by dup_and_fixup_symbol_prop().
/aliases values fall through the plain __of_prop_dup() path and are
copied byte-for-byte, so of_find_node_by_path() on such a value returns
NULL, of_alias_get_id() reports -ENODEV — and the reconfig notifier
added earlier in this series sees uninterpretable paths and can't
populate aliases_lookup for overlay-declared aliases.
The values in /aliases follow the same textual convention as
/__symbols__, so we can reuse the existing rewriter. Detect the
/aliases target node and route its properties through
dup_and_fixup_symbol_prop() only when the value actually looks like a
fragment-internal path (non-empty, null-terminated within pp->length,
"/fragment@" prefix); other alias values — legacy string aliases like
"ttyS0" that some out-of-tree code writes verbatim — pass through the
plain __of_prop_dup() path unchanged.
Discriminating up-front rather than falling back on a NULL return
matters because dup_and_fixup_symbol_prop() also returns NULL on
allocation failure and on malformed values. A blanket fallback would
mask -ENOMEM as "not our shape" and, worse, would copy a
non-null-terminated value byte-for-byte into the live tree — where
the alias reconfig notifier's downstream of_find_node_by_path() would
treat it as a C string and read past the end. Structural validation
here means a NULL from dup_and_fixup_symbol_prop() below can only be
-ENOMEM and is propagated as such.
Signed-off-by: Abdurrahman Hussain <abdurrahman@xxxxxxxxxx>
---
drivers/of/overlay.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 654a70d5cb07..69358811a7f9 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -350,6 +350,33 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
if (prop)
return -EINVAL;
new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
+ } else if (target->np->parent &&
+ of_node_is_root(target->np->parent) &&
+ of_node_name_eq(target->np, "aliases") &&
+ overlay_prop->length >= sizeof("/fragment@") &&
+ overlay_prop->value &&
+ strnlen(overlay_prop->value, overlay_prop->length) <
+ overlay_prop->length &&
+ !strncmp(overlay_prop->value, "/fragment@",
+ strlen("/fragment@"))) {
+ /*
+ * /aliases property values that reference a labeled node
+ * inside this overlay are rendered by dtc as string paths
+ * "/fragment@N/__overlay__/..." — the overlay's internal
+ * layout rather than where the node lives after apply.
+ * Reuse dup_and_fixup_symbol_prop() (which already handles
+ * this rewrite for /__symbols__) so of_alias_get_id() can
+ * resolve the value in the live tree.
+ *
+ * The property-value shape (non-empty, null-terminated
+ * within pp->length, prefix "/fragment@") is validated
+ * above so a NULL return from dup_and_fixup_symbol_prop()
+ * here means -ENOMEM, not "not our shape"; let the shared
+ * -ENOMEM check below handle it rather than falling back
+ * to a raw dup that would inject an unresolvable path
+ * into the live tree.
+ */
+ new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
} else {
new_prop = __of_prop_dup(overlay_prop, GFP_KERNEL);
}
--
2.54.0