1 From caba0117dc30f2357eac6d04f3510095dcbaa7f4 Mon Sep 17 00:00:00 2001
2 From: Paul Barker <pbarker@konsulko.com>
3 Date: Fri, 18 Dec 2020 23:00:07 +0000
4 Subject: [PATCH] fdtoverlay: Prevent overlays from modifying phandle
6 To: David Gibson <david@gibson.dropbear.id.au>,
7 Jon Loeliger <jdl@jdl.com>,
8 devicetree-compiler@vger.kernel.org
9 Cc: Rob Herring <robh@kernel.org>,
10 Pantelis Antoniou <pantelis.antoniou@konsulko.com>,
11 Scott Murray <scott.murray@konsulko.com>,
12 Jan Simon Moeller <jsmoeller@linuxfoundation.org>
14 When applying an overlay fragment, we should take care not to overwrite
15 an existing phandle property of the target node as this could break
16 references to the target node elsewhere in the base dtb.
18 In addition to potentially breaking references within the resulting fdt,
19 if the overlay is built with symbols enabled (`-@` option to dtc) then
20 fdtoverlay will be unable to merge the overlay with a base dtb file.
22 A new test case is added to check how fdtoverlay handles this case.
23 Attempting to apply this test overlay without the fix in this patch
24 results in the following output:
26 input = tests/overlay_base_ref.test.dtb
27 output = tests/overlay_overlay_ref.fdtoverlay.dtb
28 overlay[0] = tests/overlay_overlay_ref.test.dtb
30 Failed to apply 'tests/overlay_overlay_ref.test.dtb': FDT_ERR_NOTFOUND
32 In this test case the __overlay__ node in question does not explicitly
33 contain a phandle property in the dts file, the phandle is added during
34 compilation as it is referenced by another node within the overlay dts.
36 This failure occurs due to a sequence of events in the functions called
37 by fdt_overlay_apply():
39 1) In overlay_fixup_phandles(), the target of the overlay fragment is
40 looked up and the target property is set to the phandle of the target
43 2) In overlay_merge(), the target node is looked up by phandle via
44 overlay_get_target(). As the __overlay__ node in this test case
45 itself has a phandle property, the phandle of the target node is
48 3) In overlay_symbol_update(), the target node is again looked up by
49 phandle via overlay_get_target(). But this time the target node
50 cannot be found as its phandle property was modified.
52 The fix for this issue is to skip modification of the phandle property
53 of the target node in step (2) of the above sequence. If the target node
54 doesn't already contain a phandle property, we can add one without risk.
56 Upstream-Status: Submitted
57 https://www.spinics.net/lists/devicetree-compiler/msg03537.html
58 Signed-off-by: Paul Barker <pbarker@konsulko.com>
60 libfdt/fdt_overlay.c | 2 ++
61 tests/overlay_base_ref.dts | 19 +++++++++++++++++++
62 tests/overlay_overlay_ref.dts | 24 ++++++++++++++++++++++++
63 tests/run_tests.sh | 5 +++++
64 4 files changed, 50 insertions(+)
65 create mode 100644 tests/overlay_base_ref.dts
66 create mode 100644 tests/overlay_overlay_ref.dts
68 diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
69 index d217e79..b3c217a 100644
70 --- a/libfdt/fdt_overlay.c
71 +++ b/libfdt/fdt_overlay.c
72 @@ -573,6 +573,8 @@ static int overlay_apply_node(void *fdt, int target,
76 + if (!strcmp(name, "phandle") && fdt_getprop(fdt, target, name, NULL))
78 ret = fdt_setprop(fdt, target, name, prop, prop_len);
81 diff --git a/tests/overlay_base_ref.dts b/tests/overlay_base_ref.dts
83 index 0000000..1fc02a2
85 +++ b/tests/overlay_base_ref.dts
88 + * Copyright (c) 2016 NextThing Co
89 + * Copyright (c) 2016 Free Electrons
90 + * Copyright (c) 2016 Konsulko Inc.
92 + * SPDX-License-Identifier: GPL-2.0+
99 + test-int-property = <42>;
106 diff --git a/tests/overlay_overlay_ref.dts b/tests/overlay_overlay_ref.dts
108 index 0000000..a45c95d
110 +++ b/tests/overlay_overlay_ref.dts
113 + * Copyright (c) 2016 NextThing Co
114 + * Copyright (c) 2016 Free Electrons
115 + * Copyright (c) 2016 Konsulko Inc.
117 + * SPDX-License-Identifier: GPL-2.0+
127 + frag0: __overlay__ {
128 + test-int-property = <43>;
136 diff --git a/tests/run_tests.sh b/tests/run_tests.sh
137 index 294585b..a65b166 100755
138 --- a/tests/run_tests.sh
139 +++ b/tests/run_tests.sh
140 @@ -329,6 +329,11 @@ dtc_overlay_tests () {
141 run_test check_path overlay_base_with_aliases.dtb not-exists "/__symbols__"
142 run_test check_path overlay_base_with_aliases.dtb not-exists "/__fixups__"
143 run_test check_path overlay_base_with_aliases.dtb not-exists "/__local_fixups__"
145 + # Test taking a reference to an overlay fragment
146 + run_dtc_test -@ -I dts -O dtb -o overlay_base_ref.test.dtb "$SRCDIR/overlay_base_ref.dts"
147 + run_dtc_test -@ -I dts -O dtb -o overlay_overlay_ref.test.dtb "$SRCDIR/overlay_overlay_ref.dts"
148 + run_wrap_test $FDTOVERLAY -i overlay_base_ref.test.dtb overlay_overlay_ref.test.dtb -o overlay_overlay_ref.fdtoverlay.dtb