Skip to content

Commit 5e47481

Browse files
geerturobherring
authored andcommitted
of: overlay: Fix (un)locking in of_overlay_apply()
The special overlay mutex is taken first, hence it should be released last in the error path. of_resolve_phandles() must be called with of_mutex held. Without it, a node and new phandle could be added via of_attach_node(), making the max phandle wrong. free_overlay_changeset() must be called with of_mutex held, if any non-trivial cleanup is to be done. Hence move "mutex_lock(&of_mutex)" up, as suggested by Frank, and merge the two tail statements of the success and error paths, now they became identical. Note that while the two mutexes are adjacent, we still need both: __of_changeset_apply_notify(), which is called by __of_changeset_apply() unlocks of_mutex, then does notifications then locks of_mutex. So the mutex get released in the middle of of_overlay_apply() Fixes: f948d6d ("of: overlay: avoid race condition between applying multiple overlays") Signed-off-by: Geert Uytterhoeven <[email protected]> Reviewed-by: Frank Rowand <[email protected]> Signed-off-by: Rob Herring <[email protected]>
1 parent 1352f09 commit 5e47481

File tree

1 file changed

+5
-10
lines changed

1 file changed

+5
-10
lines changed

drivers/of/overlay.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -706,12 +706,11 @@ int of_overlay_apply(struct device_node *tree, int *ovcs_id)
706706
}
707707

708708
of_overlay_mutex_lock();
709+
mutex_lock(&of_mutex);
709710

710711
ret = of_resolve_phandles(tree);
711712
if (ret)
712-
goto err_overlay_unlock;
713-
714-
mutex_lock(&of_mutex);
713+
goto err_free_overlay_changeset;
715714

716715
ret = init_overlay_changeset(ovcs, tree);
717716
if (ret)
@@ -754,18 +753,14 @@ int of_overlay_apply(struct device_node *tree, int *ovcs_id)
754753
ret = ret_tmp;
755754
}
756755

757-
mutex_unlock(&of_mutex);
758-
of_overlay_mutex_unlock();
759-
760-
goto out;
761-
762-
err_overlay_unlock:
763-
of_overlay_mutex_unlock();
756+
goto out_unlock;
764757

765758
err_free_overlay_changeset:
766759
free_overlay_changeset(ovcs);
767760

761+
out_unlock:
768762
mutex_unlock(&of_mutex);
763+
of_overlay_mutex_unlock();
769764

770765
out:
771766
pr_debug("%s() err=%d\n", __func__, ret);

0 commit comments

Comments
 (0)