[PATCH v4 4/6] of/overlay: return ERR_PTR from dup_and_fixup_symbol_prop()
From: Abdurrahman Hussain
Date: Tue Jul 21 2026 - 22:49:54 EST
dup_and_fixup_symbol_prop() returns NULL for three very different
reasons: the property value is not a valid non-empty C string
(malformed input), the value does not resolve to a node inside one of
the overlay's fragments (not an overlay-internal path), and memory
allocation failure. Its only caller today reports every NULL as
-ENOMEM, so structural problems in an overlay's /__symbols__ node are
diagnosed as memory exhaustion.
The next patch reuses the helper for /aliases values, where the
distinction is load-bearing: a value that doesn't resolve inside the
overlay is a legacy alias that must be copied verbatim, a malformed
value must be admitted inertly with a warning, and only a real
allocation failure may fail the overlay apply.
Return ERR_PTR instead: -EINVAL for malformed values, -ENODEV when
the value is not a path into one of the overlay's fragments, -ENOMEM
for allocation failures. The /__symbols__ caller now propagates the
distinct errno instead of collapsing everything to -ENOMEM.
Assisted-by: Claude:claude-fable-5 [Claude Code]
Signed-off-by: Abdurrahman Hussain <abdurrahman@xxxxxxxxxx>
---
drivers/of/overlay.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index 74aea704835a..ad4e50482515 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -206,6 +206,10 @@ static void overlay_fw_devlink_refresh(struct overlay_changeset *ovcs)
* The duplicated property value will be modified by replacing the
* "/fragment_name/__overlay/" portion of the value with the target
* path from the fragment node.
+ *
+ * Return: the fixed-up property, or ERR_PTR: -EINVAL if @prop's value
+ * is not a valid non-empty C string, -ENODEV if it is not a path into
+ * one of @ovcs's fragments, -ENOMEM on allocation failure.
*/
static struct property *dup_and_fixup_symbol_prop(
struct overlay_changeset *ovcs, const struct property *prop)
@@ -224,14 +228,14 @@ static struct property *dup_and_fixup_symbol_prop(
int target_path_len;
if (!prop->value)
- return NULL;
+ return ERR_PTR(-EINVAL);
if (strnlen(prop->value, prop->length) >= prop->length)
- return NULL;
+ return ERR_PTR(-EINVAL);
path = prop->value;
path_len = strlen(path);
if (path_len < 1)
- return NULL;
+ return ERR_PTR(-EINVAL);
fragment_node = __of_find_node_by_path(ovcs->overlay_root, path + 1);
overlay_node = __of_find_node_by_path(fragment_node, "__overlay__/");
of_node_put(fragment_node);
@@ -243,18 +247,18 @@ static struct property *dup_and_fixup_symbol_prop(
break;
}
if (k >= ovcs->count)
- return NULL;
+ return ERR_PTR(-ENODEV);
overlay_name_len = snprintf(NULL, 0, "%pOF", fragment->overlay);
if (overlay_name_len > path_len)
- return NULL;
+ return ERR_PTR(-EINVAL);
path_tail = path + overlay_name_len;
path_tail_len = strlen(path_tail);
target_path = kasprintf(GFP_KERNEL, "%pOF", fragment->target);
if (!target_path)
- return NULL;
+ return ERR_PTR(-ENOMEM);
target_path_len = strlen(target_path);
new_prop = kzalloc_obj(*new_prop);
@@ -281,7 +285,7 @@ static struct property *dup_and_fixup_symbol_prop(
err_free_target_path:
kfree(target_path);
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
/**
@@ -350,6 +354,8 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
if (prop)
return -EINVAL;
new_prop = dup_and_fixup_symbol_prop(ovcs, overlay_prop);
+ if (IS_ERR(new_prop))
+ return PTR_ERR(new_prop);
} else {
new_prop = __of_prop_dup(overlay_prop, GFP_KERNEL);
}
--
2.54.0