| .. | .. |
|---|
| 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) |
|---|