[PATCH 3/5] of: dynamic: Fix race in getting old property when updating property

From: Rob Herring
Date: Tue Aug 01 2023 - 17:55:31 EST


__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@xxxxxxxxxx>
---
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 aa3821836937..31603b5a4ffc 100644
--- a/drivers/of/dynamic.c
+++ b/drivers/of/dynamic.c
@@ -565,7 +565,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;

@@ -606,7 +606,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