[PATCH v3 4/6] of: dynamic: Fix race in getting old property when updating property

Rob Herring posted 6 patches 2 years ago
Only 5 patches received!
[PATCH v3 4/6] of: dynamic: Fix race in getting old property when updating property
Posted by Rob Herring 2 years ago
__of_update_property() returns the existing property if there is one, but
that value is never added to the changeset. Updates work because the
existing property is also retrieved in of_changeset_action(), but that is
racy as of_changeset_action() doesn't hold any locks. The property could
be changed before the changeset is applied.

Signed-off-by: Rob Herring <robh@kernel.org>
---
 drivers/of/dynamic.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c
index 17a0727d3f9b..1876af5b01fc 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -564,7 +564,7 @@ static int __of_changeset_entry_notify(struct of_changeset_entry *ce,
 
 static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
 {
-	struct property *old_prop, **propp;
+	struct property **propp;
 	unsigned long flags;
 	int ret = 0;
 
@@ -604,7 +604,7 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce)
 			}
 		}
 
-		ret = __of_update_property(ce->np, ce->prop, &old_prop);
+		ret = __of_update_property(ce->np, ce->prop, &ce->old_prop);
 		break;
 	default:
 		ret = -EINVAL;
@@ -908,9 +908,6 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action,
 	ce->np = of_node_get(np);
 	ce->prop = prop;
 
-	if (action == OF_RECONFIG_UPDATE_PROPERTY && prop)
-		ce->old_prop = of_find_property(np, prop->name, NULL);
-
 	/* add it to the list */
 	list_add_tail(&ce->node, &ocs->entries);
 	return 0;

-- 
2.40.1
Re: [PATCH v3 4/6] of: dynamic: Fix race in getting old property when updating property
Posted by Geert Uytterhoeven 2 years ago
Hi Rob,

Thanks for your patch!

On Fri, Aug 18, 2023 at 10:41 PM Rob Herring <robh@kernel.org> wrote:
> __of_update_property() returns the existing property if there is one, but
> that value is never added to the changeset. Updates work because the
> existing property is also retrieved in of_changeset_action(), but that is

Perhaps s/is also retrieved/was also retrieved before/, as
of_overlay_apply() calls build_changeset() before
__of_changeset_apply_entries()?

> racy as of_changeset_action() doesn't hold any locks. The property could
> be changed before the changeset is applied.
>
> Signed-off-by: Rob Herring <robh@kernel.org>

Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds