.. | .. |
---|
| 1 | +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) |
---|
1 | 2 | /* |
---|
2 | 3 | * libfdt - Flat Device Tree manipulation |
---|
3 | 4 | * Copyright (C) 2016 Free Electrons |
---|
4 | 5 | * Copyright (C) 2016 NextThing Co. |
---|
5 | | - * |
---|
6 | | - * libfdt is dual licensed: you can use it either under the terms of |
---|
7 | | - * the GPL, or the BSD license, at your option. |
---|
8 | | - * |
---|
9 | | - * a) This library is free software; you can redistribute it and/or |
---|
10 | | - * modify it under the terms of the GNU General Public License as |
---|
11 | | - * published by the Free Software Foundation; either version 2 of the |
---|
12 | | - * License, or (at your option) any later version. |
---|
13 | | - * |
---|
14 | | - * This library is distributed in the hope that it will be useful, |
---|
15 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
16 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
17 | | - * GNU General Public License for more details. |
---|
18 | | - * |
---|
19 | | - * You should have received a copy of the GNU General Public |
---|
20 | | - * License along with this library; if not, write to the Free |
---|
21 | | - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, |
---|
22 | | - * MA 02110-1301 USA |
---|
23 | | - * |
---|
24 | | - * Alternatively, |
---|
25 | | - * |
---|
26 | | - * b) Redistribution and use in source and binary forms, with or |
---|
27 | | - * without modification, are permitted provided that the following |
---|
28 | | - * conditions are met: |
---|
29 | | - * |
---|
30 | | - * 1. Redistributions of source code must retain the above |
---|
31 | | - * copyright notice, this list of conditions and the following |
---|
32 | | - * disclaimer. |
---|
33 | | - * 2. Redistributions in binary form must reproduce the above |
---|
34 | | - * copyright notice, this list of conditions and the following |
---|
35 | | - * disclaimer in the documentation and/or other materials |
---|
36 | | - * provided with the distribution. |
---|
37 | | - * |
---|
38 | | - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
---|
39 | | - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
---|
40 | | - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
---|
41 | | - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
---|
42 | | - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
---|
43 | | - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
---|
44 | | - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
---|
45 | | - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
---|
46 | | - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
47 | | - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
48 | | - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
---|
49 | | - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
---|
50 | | - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
51 | 6 | */ |
---|
52 | 7 | #include "libfdt_env.h" |
---|
53 | 8 | |
---|
.. | .. |
---|
93 | 48 | * @pathp: pointer which receives the path of the target (or NULL) |
---|
94 | 49 | * |
---|
95 | 50 | * overlay_get_target() retrieves the target offset in the base |
---|
96 | | - * device tree of a fragment, no matter how the actual targetting is |
---|
| 51 | + * device tree of a fragment, no matter how the actual targeting is |
---|
97 | 52 | * done (through a phandle or a path) |
---|
98 | 53 | * |
---|
99 | 54 | * returns: |
---|
100 | | - * the targetted node offset in the base device tree |
---|
| 55 | + * the targeted node offset in the base device tree |
---|
101 | 56 | * Negative error code on error |
---|
102 | 57 | */ |
---|
103 | 58 | static int overlay_get_target(const void *fdt, const void *fdto, |
---|
.. | .. |
---|
286 | 241 | |
---|
287 | 242 | if (fixup_len % sizeof(uint32_t)) |
---|
288 | 243 | return -FDT_ERR_BADOVERLAY; |
---|
| 244 | + fixup_len /= sizeof(uint32_t); |
---|
289 | 245 | |
---|
290 | 246 | tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); |
---|
291 | 247 | if (!tree_val) { |
---|
.. | .. |
---|
295 | 251 | return tree_len; |
---|
296 | 252 | } |
---|
297 | 253 | |
---|
298 | | - for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) { |
---|
| 254 | + for (i = 0; i < fixup_len; i++) { |
---|
299 | 255 | fdt32_t adj_val; |
---|
300 | 256 | uint32_t poffset; |
---|
301 | 257 | |
---|
.. | .. |
---|
697 | 653 | int len = 0, namelen; |
---|
698 | 654 | const char *name; |
---|
699 | 655 | |
---|
700 | | - FDT_CHECK_HEADER(fdt); |
---|
| 656 | + FDT_RO_PROBE(fdt); |
---|
701 | 657 | |
---|
702 | 658 | for (;;) { |
---|
703 | 659 | name = fdt_get_name(fdt, nodeoffset, &namelen); |
---|
.. | .. |
---|
778 | 734 | /* keep end marker to avoid strlen() */ |
---|
779 | 735 | e = path + path_len; |
---|
780 | 736 | |
---|
781 | | - /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */ |
---|
782 | | - |
---|
783 | 737 | if (*path != '/') |
---|
784 | 738 | return -FDT_ERR_BADVALUE; |
---|
785 | 739 | |
---|
786 | 740 | /* get fragment name first */ |
---|
787 | 741 | s = strchr(path + 1, '/'); |
---|
788 | | - if (!s) |
---|
789 | | - return -FDT_ERR_BADOVERLAY; |
---|
| 742 | + if (!s) { |
---|
| 743 | + /* Symbol refers to something that won't end |
---|
| 744 | + * up in the target tree */ |
---|
| 745 | + continue; |
---|
| 746 | + } |
---|
790 | 747 | |
---|
791 | 748 | frag_name = path + 1; |
---|
792 | 749 | frag_name_len = s - path - 1; |
---|
793 | 750 | |
---|
794 | 751 | /* verify format; safe since "s" lies in \0 terminated prop */ |
---|
795 | 752 | len = sizeof("/__overlay__/") - 1; |
---|
796 | | - if ((e - s) < len || memcmp(s, "/__overlay__/", len)) |
---|
797 | | - return -FDT_ERR_BADOVERLAY; |
---|
798 | | - |
---|
799 | | - rel_path = s + len; |
---|
800 | | - rel_path_len = e - rel_path; |
---|
| 753 | + if ((e - s) > len && (memcmp(s, "/__overlay__/", len) == 0)) { |
---|
| 754 | + /* /<fragment-name>/__overlay__/<relative-subnode-path> */ |
---|
| 755 | + rel_path = s + len; |
---|
| 756 | + rel_path_len = e - rel_path - 1; |
---|
| 757 | + } else if ((e - s) == len |
---|
| 758 | + && (memcmp(s, "/__overlay__", len - 1) == 0)) { |
---|
| 759 | + /* /<fragment-name>/__overlay__ */ |
---|
| 760 | + rel_path = ""; |
---|
| 761 | + rel_path_len = 0; |
---|
| 762 | + } else { |
---|
| 763 | + /* Symbol refers to something that won't end |
---|
| 764 | + * up in the target tree */ |
---|
| 765 | + continue; |
---|
| 766 | + } |
---|
801 | 767 | |
---|
802 | 768 | /* find the fragment index in which the symbol lies */ |
---|
803 | 769 | ret = fdt_subnode_offset_namelen(fdto, 0, frag_name, |
---|
.. | .. |
---|
863 | 829 | |
---|
864 | 830 | int fdt_overlay_apply(void *fdt, void *fdto) |
---|
865 | 831 | { |
---|
866 | | - uint32_t delta = fdt_get_max_phandle(fdt); |
---|
| 832 | + uint32_t delta; |
---|
867 | 833 | int ret; |
---|
868 | 834 | |
---|
869 | | - FDT_CHECK_HEADER(fdt); |
---|
870 | | - FDT_CHECK_HEADER(fdto); |
---|
| 835 | + FDT_RO_PROBE(fdt); |
---|
| 836 | + FDT_RO_PROBE(fdto); |
---|
| 837 | + |
---|
| 838 | + ret = fdt_find_max_phandle(fdt, &delta); |
---|
| 839 | + if (ret) |
---|
| 840 | + goto err; |
---|
871 | 841 | |
---|
872 | 842 | ret = overlay_adjust_local_phandles(fdto, delta); |
---|
873 | 843 | if (ret) |
---|