Skip to content

Commit 4d4d23e

Browse files
robherringopsiff
authored andcommitted
of: Add a helper to free property struct
[ Upstream commit 1c5e3d9 ] Freeing a property struct is 3 kfree()'s which is duplicated in multiple spots. Add a helper, __of_prop_free(), and replace all the open coded cases in the DT code. Reviewed-by: Saravana Kannan <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Rob Herring <[email protected]> Stable-dep-of: 80af3745ca46 ("of: dynamic: Fix use after free in of_changeset_add_prop_helper()") Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 749137b41e7064ee8b8b1f04a5a27478226d09fc)
1 parent 3926080 commit 4d4d23e

File tree

4 files changed

+19
-31
lines changed

4 files changed

+19
-31
lines changed

drivers/of/dynamic.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -306,15 +306,20 @@ int of_detach_node(struct device_node *np)
306306
}
307307
EXPORT_SYMBOL_GPL(of_detach_node);
308308

309+
void __of_prop_free(struct property *prop)
310+
{
311+
kfree(prop->name);
312+
kfree(prop->value);
313+
kfree(prop);
314+
}
315+
309316
static void property_list_free(struct property *prop_list)
310317
{
311318
struct property *prop, *next;
312319

313320
for (prop = prop_list; prop != NULL; prop = next) {
314321
next = prop->next;
315-
kfree(prop->name);
316-
kfree(prop->value);
317-
kfree(prop);
322+
__of_prop_free(prop);
318323
}
319324
}
320325

@@ -427,9 +432,7 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags)
427432
return new;
428433

429434
err_free:
430-
kfree(new->name);
431-
kfree(new->value);
432-
kfree(new);
435+
__of_prop_free(new);
433436
return NULL;
434437
}
435438

@@ -471,9 +474,7 @@ struct device_node *__of_node_dup(const struct device_node *np,
471474
if (!new_pp)
472475
goto err_prop;
473476
if (__of_add_property(node, new_pp)) {
474-
kfree(new_pp->name);
475-
kfree(new_pp->value);
476-
kfree(new_pp);
477+
__of_prop_free(new_pp);
477478
goto err_prop;
478479
}
479480
}
@@ -933,11 +934,8 @@ static int of_changeset_add_prop_helper(struct of_changeset *ocs,
933934
return -ENOMEM;
934935

935936
ret = of_changeset_add_property(ocs, np, new_pp);
936-
if (ret) {
937-
kfree(new_pp->name);
938-
kfree(new_pp->value);
939-
kfree(new_pp);
940-
}
937+
if (ret)
938+
__of_prop_free(new_pp);
941939

942940
new_pp->next = np->deadprops;
943941
np->deadprops = new_pp;

drivers/of/of_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ extern void *__unflatten_device_tree(const void *blob,
123123
* own the devtree lock or work on detached trees only.
124124
*/
125125
struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags);
126+
void __of_prop_free(struct property *prop);
126127
struct device_node *__of_node_dup(const struct device_node *np,
127128
const char *full_name);
128129

drivers/of/overlay.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,7 @@ static struct property *dup_and_fixup_symbol_prop(
262262
return new_prop;
263263

264264
err_free_new_prop:
265-
kfree(new_prop->name);
266-
kfree(new_prop->value);
267-
kfree(new_prop);
265+
__of_prop_free(new_prop);
268266
err_free_target_path:
269267
kfree(target_path);
270268

@@ -361,11 +359,8 @@ static int add_changeset_property(struct overlay_changeset *ovcs,
361359
pr_err("WARNING: memory leak will occur if overlay removed, property: %pOF/%s\n",
362360
target->np, new_prop->name);
363361

364-
if (ret) {
365-
kfree(new_prop->name);
366-
kfree(new_prop->value);
367-
kfree(new_prop);
368-
}
362+
if (ret)
363+
__of_prop_free(new_prop);
369364
return ret;
370365
}
371366

drivers/of/unittest.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -800,15 +800,11 @@ static void __init of_unittest_property_copy(void)
800800

801801
new = __of_prop_dup(&p1, GFP_KERNEL);
802802
unittest(new && propcmp(&p1, new), "empty property didn't copy correctly\n");
803-
kfree(new->value);
804-
kfree(new->name);
805-
kfree(new);
803+
__of_prop_free(new);
806804

807805
new = __of_prop_dup(&p2, GFP_KERNEL);
808806
unittest(new && propcmp(&p2, new), "non-empty property didn't copy correctly\n");
809-
kfree(new->value);
810-
kfree(new->name);
811-
kfree(new);
807+
__of_prop_free(new);
812808
#endif
813809
}
814810

@@ -3665,9 +3661,7 @@ static __init void of_unittest_overlay_high_level(void)
36653661
goto err_unlock;
36663662
}
36673663
if (__of_add_property(of_symbols, new_prop)) {
3668-
kfree(new_prop->name);
3669-
kfree(new_prop->value);
3670-
kfree(new_prop);
3664+
__of_prop_free(new_prop);
36713665
/* "name" auto-generated by unflatten */
36723666
if (!strcmp(prop->name, "name"))
36733667
continue;

0 commit comments

Comments
 (0)