History

scripts/dtc: Update to upstream version v1.6.0-2-g87a656ae5ff9

This adds the following commits from upstream: 87a656ae5ff9 check: Inform about missing ranges 73d6e9ecb417 libfdt: fix undefined behaviour in fdt_splice_() 2525da3dba9b Bump version to v1.6.0 62cb4ad286ff Execute tests on FreeBSD with Cirrus CI 1f9a41750883 tests: Allow running the testsuite on already installed binary / libraries c5995ddf4c20 tests: Honour NO_YAML make variable e4ce227e89d7 tests: Properly clean up .bak file from tests 9b75292c335c tests: Honour $(NO_PYTHON) flag from Makefile in run_tests.sh 6c253afd07d4 Encode $(NO_PYTHON) consistently with other variables 95ec8ef706bd tests: No need to explicitly pass $PYTHON from Make to run_tests.sh 2b5f62d109a2 tests: Let run_tests.sh run Python tests without Makefile assistance 76b43dcbd18a checks: Add 'dma-ranges' check e5c92a4780c6 libfdt: Use VALID_INPUT for FDT_ERR_BADSTATE checks e5cc26b68bc0 libfdt: Add support for disabling internal checks 28fd7590aad2 libfdt: Improve comments in some of the assumptions fc207c32341b libfdt: Fix a few typos 0f61c72dedc4 libfdt: Allow exclusion of fdt_check_full() f270f45fd5d2 libfdt: Add support for disabling ordering check/fixup c18bae9a4c96 libfdt: Add support for disabling version checks fc03c4a2e04e libfdt: Add support for disabling rollback handling 77563ae72b7c libfdt: Add support for disabling sanity checks 57bc6327b80b libfdt: Add support for disabling dtb checks 464962489dcc Add a way to control the level of checks in the code 0c5326cb2845 libfdt: De-inline fdt_header_size() cc6a5a071504 Revert "yamltree: Ensure consistent bracketing of properties with phandles" 0e9225eb0dfe Remove redundant YYLOC global declaration cab09eedd644 Move -DNO_VALGRIND into CPPFLAGS 0eb1cb0b531e Makefile: pass $(CFLAGS) also during dependency generation

Rob Herring committed 6 years ago

Commit d047cd81 parent 78154219 files · +296 −166Browse files

Showing the changes to scripts (9 of 9 files). Show all

Unified · Split

9 files
  1. scripts/dtc/checks.c +14 −11
  2. scripts/dtc/dtc-lexer.l +0 −1
  3. scripts/dtc/libfdt/fdt.c +62 −37
  4. scripts/dtc/libfdt/fdt_ro.c +51 −92
  5. scripts/dtc/libfdt/fdt_rw.c +29 −13
  6. scripts/dtc/libfdt/fdt_sw.c +12 −7
  7. scripts/dtc/libfdt/libfdt.h +5 −4
  8. scripts/dtc/libfdt/libfdt_internal.h +122 −0
  9. scripts/dtc/version_gen.h +1 −1
scripts/dtc/checks.c+14−11
@@ -352,7 +352,7 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, · 351 unmodified lines
352 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");352 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");
353 } else {353 } else {
354 if (unitname[0])354 if (unitname[0])
355 FAIL(c, dti, node, "node has a unit name, but no reg property");355 FAIL(c, dti, node, "node has a unit name, but no reg or ranges property");
356 }356 }
357}357}
358WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);358WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
@@ -765,13 +765,15 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, · 406 unmodified lines
765{765{
766 struct property *prop;766 struct property *prop;
767 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;767 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
768 const char *ranges = c->data;
768 769
769 prop = get_property(node, "ranges");770 prop = get_property(node, ranges);
770 if (!prop)771 if (!prop)
771 return;772 return;
772 773
773 if (!node->parent) {774 if (!node->parent) {
774 FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property");775 FAIL_PROP(c, dti, node, prop, "Root node has a \"%s\" property",
776 ranges);
775 return;777 return;
776 }778 }
777 779
@@ -783,23 +785,24 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, · 5 unmodified lines
783 785
784 if (prop->val.len == 0) {786 if (prop->val.len == 0) {
785 if (p_addr_cells != c_addr_cells)787 if (p_addr_cells != c_addr_cells)
786 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "788 FAIL_PROP(c, dti, node, prop, "empty \"%s\" property but its "
787 "#address-cells (%d) differs from %s (%d)",789 "#address-cells (%d) differs from %s (%d)",
788 c_addr_cells, node->parent->fullpath,790 ranges, c_addr_cells, node->parent->fullpath,
789 p_addr_cells);791 p_addr_cells);
790 if (p_size_cells != c_size_cells)792 if (p_size_cells != c_size_cells)
791 FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "793 FAIL_PROP(c, dti, node, prop, "empty \"%s\" property but its "
792 "#size-cells (%d) differs from %s (%d)",794 "#size-cells (%d) differs from %s (%d)",
793 c_size_cells, node->parent->fullpath,795 ranges, c_size_cells, node->parent->fullpath,
794 p_size_cells);796 p_size_cells);
795 } else if ((prop->val.len % entrylen) != 0) {797 } else if ((prop->val.len % entrylen) != 0) {
796 FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) "798 FAIL_PROP(c, dti, node, prop, "\"%s\" property has invalid length (%d bytes) "
797 "(parent #address-cells == %d, child #address-cells == %d, "799 "(parent #address-cells == %d, child #address-cells == %d, "
798 "#size-cells == %d)", prop->val.len,800 "#size-cells == %d)", ranges, prop->val.len,
799 p_addr_cells, c_addr_cells, c_size_cells);801 p_addr_cells, c_addr_cells, c_size_cells);
800 }802 }
801}803}
802WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);804WARNING(ranges_format, check_ranges_format, "ranges", &addr_size_cells);
805WARNING(dma_ranges_format, check_ranges_format, "dma-ranges", &addr_size_cells);
803 806
804static const struct bus_type pci_bus = {807static const struct bus_type pci_bus = {
805 .name = "PCI",808 .name = "PCI",
@@ -1780,7 +1783,7 @@ static struct check *check_table[] = { · 974 unmodified lines
1780 &property_name_chars_strict,1783 &property_name_chars_strict,
1781 &node_name_chars_strict,1784 &node_name_chars_strict,
1782 1785
1783 &addr_size_cells, &reg_format, &ranges_format,1786 &addr_size_cells, &reg_format, &ranges_format, &dma_ranges_format,
1784 1787
1785 &unit_address_vs_reg,1788 &unit_address_vs_reg,
1786 &unit_address_format,1789 &unit_address_format,
scripts/dtc/dtc-lexer.l+0−1
@@ -23,7 +23,6 @@ LINECOMMENT "//".*\n · 22 unmodified lines
23#include "srcpos.h"23#include "srcpos.h"
24#include "dtc-parser.tab.h"24#include "dtc-parser.tab.h"
25 25
26YYLTYPE yylloc;
27extern bool treesource_error;26extern bool treesource_error;
28 27
29/* CAUTION: this will stop working if we ever use yyless() or yyunput() */28/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
scripts/dtc/libfdt/fdt.c+62−37
@@ -19,15 +19,21 @@ int32_t fdt_ro_probe_(const void *fdt) · 18 unmodified lines
19{19{
20 uint32_t totalsize = fdt_totalsize(fdt);20 uint32_t totalsize = fdt_totalsize(fdt);
21 21
22 if (can_assume(VALID_DTB))
23 return totalsize;
24
22 if (fdt_magic(fdt) == FDT_MAGIC) {25 if (fdt_magic(fdt) == FDT_MAGIC) {
23 /* Complete tree */26 /* Complete tree */
24 if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)27 if (!can_assume(LATEST)) {
25 return -FDT_ERR_BADVERSION;28 if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
26 if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)29 return -FDT_ERR_BADVERSION;
27 return -FDT_ERR_BADVERSION;30 if (fdt_last_comp_version(fdt) >
31 FDT_LAST_SUPPORTED_VERSION)
32 return -FDT_ERR_BADVERSION;
33 }
28 } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {34 } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
29 /* Unfinished sequential-write blob */35 /* Unfinished sequential-write blob */
30 if (fdt_size_dt_struct(fdt) == 0)36 if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0)
31 return -FDT_ERR_BADSTATE;37 return -FDT_ERR_BADSTATE;
32 } else {38 } else {
33 return -FDT_ERR_BADMAGIC;39 return -FDT_ERR_BADMAGIC;
@@ -70,44 +76,59 @@ size_t fdt_header_size_(uint32_t version) · 36 unmodified lines
70 return FDT_V17_SIZE;76 return FDT_V17_SIZE;
71}77}
72 78
79size_t fdt_header_size(const void *fdt)
80{
81 return can_assume(LATEST) ? FDT_V17_SIZE :
82 fdt_header_size_(fdt_version(fdt));
83}
84
73int fdt_check_header(const void *fdt)85int fdt_check_header(const void *fdt)
74{86{
75 size_t hdrsize;87 size_t hdrsize;
76 88
77 if (fdt_magic(fdt) != FDT_MAGIC)89 if (fdt_magic(fdt) != FDT_MAGIC)
78 return -FDT_ERR_BADMAGIC;90 return -FDT_ERR_BADMAGIC;
91 if (!can_assume(LATEST)) {
92 if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
93 || (fdt_last_comp_version(fdt) >
94 FDT_LAST_SUPPORTED_VERSION))
95 return -FDT_ERR_BADVERSION;
96 if (fdt_version(fdt) < fdt_last_comp_version(fdt))
97 return -FDT_ERR_BADVERSION;
98 }
79 hdrsize = fdt_header_size(fdt);99 hdrsize = fdt_header_size(fdt);
80 if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)100 if (!can_assume(VALID_DTB)) {
81 || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))
82 return -FDT_ERR_BADVERSION;
83 if (fdt_version(fdt) < fdt_last_comp_version(fdt))
84 return -FDT_ERR_BADVERSION;
85
86 if ((fdt_totalsize(fdt) < hdrsize)
87 || (fdt_totalsize(fdt) > INT_MAX))
88 return -FDT_ERR_TRUNCATED;
89 101
90 /* Bounds check memrsv block */102 if ((fdt_totalsize(fdt) < hdrsize)
91 if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))103 || (fdt_totalsize(fdt) > INT_MAX))
92 return -FDT_ERR_TRUNCATED;104 return -FDT_ERR_TRUNCATED;
93 105
94 /* Bounds check structure block */106 /* Bounds check memrsv block */
95 if (fdt_version(fdt) < 17) {
96 if (!check_off_(hdrsize, fdt_totalsize(fdt),107 if (!check_off_(hdrsize, fdt_totalsize(fdt),
97 fdt_off_dt_struct(fdt)))108 fdt_off_mem_rsvmap(fdt)))
98 return -FDT_ERR_TRUNCATED;109 return -FDT_ERR_TRUNCATED;
99 } else {110 }
111
112 if (!can_assume(VALID_DTB)) {
113 /* Bounds check structure block */
114 if (!can_assume(LATEST) && fdt_version(fdt) < 17) {
115 if (!check_off_(hdrsize, fdt_totalsize(fdt),
116 fdt_off_dt_struct(fdt)))
117 return -FDT_ERR_TRUNCATED;
118 } else {
119 if (!check_block_(hdrsize, fdt_totalsize(fdt),
120 fdt_off_dt_struct(fdt),
121 fdt_size_dt_struct(fdt)))
122 return -FDT_ERR_TRUNCATED;
123 }
124
125 /* Bounds check strings block */
100 if (!check_block_(hdrsize, fdt_totalsize(fdt),126 if (!check_block_(hdrsize, fdt_totalsize(fdt),
101 fdt_off_dt_struct(fdt),127 fdt_off_dt_strings(fdt),
102 fdt_size_dt_struct(fdt)))128 fdt_size_dt_strings(fdt)))
103 return -FDT_ERR_TRUNCATED;129 return -FDT_ERR_TRUNCATED;
104 }130 }
105 131
106 /* Bounds check strings block */
107 if (!check_block_(hdrsize, fdt_totalsize(fdt),
108 fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))
109 return -FDT_ERR_TRUNCATED;
110
111 return 0;132 return 0;
112}133}
113 134
@@ -115,12 +136,13 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) · 1 unmodified line
115{136{
116 unsigned absoffset = offset + fdt_off_dt_struct(fdt);137 unsigned absoffset = offset + fdt_off_dt_struct(fdt);
117 138
118 if ((absoffset < offset)139 if (!can_assume(VALID_INPUT))
119 || ((absoffset + len) < absoffset)140 if ((absoffset < offset)
120 || (absoffset + len) > fdt_totalsize(fdt))141 || ((absoffset + len) < absoffset)
121 return NULL;142 || (absoffset + len) > fdt_totalsize(fdt))
143 return NULL;
122 144
123 if (fdt_version(fdt) >= 0x11)145 if (can_assume(LATEST) || fdt_version(fdt) >= 0x11)
124 if (((offset + len) < offset)146 if (((offset + len) < offset)
125 || ((offset + len) > fdt_size_dt_struct(fdt)))147 || ((offset + len) > fdt_size_dt_struct(fdt)))
126 return NULL;148 return NULL;
@@ -137,7 +159,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) · 10 unmodified lines
137 159
138 *nextoffset = -FDT_ERR_TRUNCATED;160 *nextoffset = -FDT_ERR_TRUNCATED;
139 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);161 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
140 if (!tagp)162 if (!can_assume(VALID_DTB) && !tagp)
141 return FDT_END; /* premature end */163 return FDT_END; /* premature end */
142 tag = fdt32_to_cpu(*tagp);164 tag = fdt32_to_cpu(*tagp);
143 offset += FDT_TAGSIZE;165 offset += FDT_TAGSIZE;
@@ -149,18 +171,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) · 5 unmodified lines
149 do {171 do {
150 p = fdt_offset_ptr(fdt, offset++, 1);172 p = fdt_offset_ptr(fdt, offset++, 1);
151 } while (p && (*p != '\0'));173 } while (p && (*p != '\0'));
152 if (!p)174 if (!can_assume(VALID_DTB) && !p)
153 return FDT_END; /* premature end */175 return FDT_END; /* premature end */
154 break;176 break;
155 177
156 case FDT_PROP:178 case FDT_PROP:
157 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));179 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
158 if (!lenp)180 if (!can_assume(VALID_DTB) && !lenp)
159 return FDT_END; /* premature end */181 return FDT_END; /* premature end */
160 /* skip-name offset, length and value */182 /* skip-name offset, length and value */
161 offset += sizeof(struct fdt_property) - FDT_TAGSIZE183 offset += sizeof(struct fdt_property) - FDT_TAGSIZE
162 + fdt32_to_cpu(*lenp);184 + fdt32_to_cpu(*lenp);
163 if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&185 if (!can_assume(LATEST) &&
186 fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
164 ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)187 ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
165 offset += 4;188 offset += 4;
166 break;189 break;
@@ -183,6 +206,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) · 16 unmodified lines
183 206
184int fdt_check_node_offset_(const void *fdt, int offset)207int fdt_check_node_offset_(const void *fdt, int offset)
185{208{
209 if (can_assume(VALID_INPUT))
210 return offset;
186 if ((offset < 0) || (offset % FDT_TAGSIZE)211 if ((offset < 0) || (offset % FDT_TAGSIZE)
187 || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))212 || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
188 return -FDT_ERR_BADOFFSET;213 return -FDT_ERR_BADOFFSET;
scripts/dtc/libfdt/fdt_ro.c+51−92
@@ -33,17 +33,26 @@ static int fdt_nodename_eq_(const void *fdt, int offset, · 32 unmodified lines
33 33
34const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)34const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
35{35{
36 int32_t totalsize = fdt_ro_probe_(fdt);36 int32_t totalsize;
37 uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);37 uint32_t absoffset;
38 size_t len;38 size_t len;
39 int err;39 int err;
40 const char *s, *n;40 const char *s, *n;
41 41
42 if (can_assume(VALID_INPUT)) {
43 s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
44
45 if (lenp)
46 *lenp = strlen(s);
47 return s;
48 }
49 totalsize = fdt_ro_probe_(fdt);
42 err = totalsize;50 err = totalsize;
43 if (totalsize < 0)51 if (totalsize < 0)
44 goto fail;52 goto fail;
45 53
46 err = -FDT_ERR_BADOFFSET;54 err = -FDT_ERR_BADOFFSET;
55 absoffset = stroffset + fdt_off_dt_strings(fdt);
47 if (absoffset >= totalsize)56 if (absoffset >= totalsize)
48 goto fail;57 goto fail;
49 len = totalsize - absoffset;58 len = totalsize - absoffset;
@@ -51,7 +60,7 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) · 1 unmodified line
51 if (fdt_magic(fdt) == FDT_MAGIC) {60 if (fdt_magic(fdt) == FDT_MAGIC) {
52 if (stroffset < 0)61 if (stroffset < 0)
53 goto fail;62 goto fail;
54 if (fdt_version(fdt) >= 17) {63 if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
55 if (stroffset >= fdt_size_dt_strings(fdt))64 if (stroffset >= fdt_size_dt_strings(fdt))
56 goto fail;65 goto fail;
57 if ((fdt_size_dt_strings(fdt) - stroffset) < len)66 if ((fdt_size_dt_strings(fdt) - stroffset) < len)
@@ -151,10 +160,13 @@ static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) · 93 unmodified lines
151 int offset = n * sizeof(struct fdt_reserve_entry);160 int offset = n * sizeof(struct fdt_reserve_entry);
152 int absoffset = fdt_off_mem_rsvmap(fdt) + offset;161 int absoffset = fdt_off_mem_rsvmap(fdt) + offset;
153 162
154 if (absoffset < fdt_off_mem_rsvmap(fdt))163 if (!can_assume(VALID_INPUT)) {
155 return NULL;164 if (absoffset < fdt_off_mem_rsvmap(fdt))
156 if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))165 return NULL;
157 return NULL;166 if (absoffset > fdt_totalsize(fdt) -
167 sizeof(struct fdt_reserve_entry))
168 return NULL;
169 }
158 return fdt_mem_rsv_(fdt, n);170 return fdt_mem_rsv_(fdt, n);
159}171}
160 172
@@ -164,7 +176,7 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) · 3 unmodified lines
164 176
165 FDT_RO_PROBE(fdt);177 FDT_RO_PROBE(fdt);
166 re = fdt_mem_rsv(fdt, n);178 re = fdt_mem_rsv(fdt, n);
167 if (!re)179 if (!can_assume(VALID_INPUT) && !re)
168 return -FDT_ERR_BADOFFSET;180 return -FDT_ERR_BADOFFSET;
169 181
170 *address = fdt64_ld(&re->address);182 *address = fdt64_ld(&re->address);
@@ -295,7 +307,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) · 124 unmodified lines
295 307
296 nameptr = nh->name;308 nameptr = nh->name;
297 309
298 if (fdt_version(fdt) < 0x10) {310 if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
299 /*311 /*
300 * For old FDT versions, match the naming conventions of V16:312 * For old FDT versions, match the naming conventions of V16:
301 * give only the leaf name (after all /). The actual tree313 * give only the leaf name (after all /). The actual tree
@@ -346,7 +358,8 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, · 44 unmodified lines
346 int err;358 int err;
347 const struct fdt_property *prop;359 const struct fdt_property *prop;
348 360
349 if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {361 if (!can_assume(VALID_INPUT) &&
362 (err = fdt_check_prop_offset_(fdt, offset)) < 0) {
350 if (lenp)363 if (lenp)
351 *lenp = err;364 *lenp = err;
352 return NULL;365 return NULL;
@@ -367,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, · 14 unmodified lines
367 /* Prior to version 16, properties may need realignment380 /* Prior to version 16, properties may need realignment
368 * and this API does not work. fdt_getprop_*() will, however. */381 * and this API does not work. fdt_getprop_*() will, however. */
369 382
370 if (fdt_version(fdt) < 0x10) {383 if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
371 if (lenp)384 if (lenp)
372 *lenp = -FDT_ERR_BADVERSION;385 *lenp = -FDT_ERR_BADVERSION;
373 return NULL;386 return NULL;
@@ -388,7 +401,8 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, · 14 unmodified lines
388 (offset = fdt_next_property_offset(fdt, offset))) {401 (offset = fdt_next_property_offset(fdt, offset))) {
389 const struct fdt_property *prop;402 const struct fdt_property *prop;
390 403
391 if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {404 prop = fdt_get_property_by_offset_(fdt, offset, lenp);
405 if (!can_assume(LIBFDT_FLAWLESS) && !prop) {
392 offset = -FDT_ERR_INTERNAL;406 offset = -FDT_ERR_INTERNAL;
393 break;407 break;
394 }408 }
@@ -413,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, · 18 unmodified lines
413{427{
414 /* Prior to version 16, properties may need realignment428 /* Prior to version 16, properties may need realignment
415 * and this API does not work. fdt_getprop_*() will, however. */429 * and this API does not work. fdt_getprop_*() will, however. */
416 if (fdt_version(fdt) < 0x10) {430 if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
417 if (lenp)431 if (lenp)
418 *lenp = -FDT_ERR_BADVERSION;432 *lenp = -FDT_ERR_BADVERSION;
419 return NULL;433 return NULL;
@@ -444,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, · 24 unmodified lines
444 return NULL;458 return NULL;
445 459
446 /* Handle realignment */460 /* Handle realignment */
447 if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&461 if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
448 fdt32_ld(&prop->len) >= 8)462 (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
449 return prop->data + 4;463 return prop->data + 4;
450 return prop->data;464 return prop->data;
451}465}
@@ -461,19 +475,24 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, · 9 unmodified lines
461 if (namep) {475 if (namep) {
462 const char *name;476 const char *name;
463 int namelen;477 int namelen;
464 name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),478
465 &namelen);479 if (!can_assume(VALID_INPUT)) {
466 if (!name) {480 name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
467 if (lenp)481 &namelen);
468 *lenp = namelen;482 if (!name) {
469 return NULL;483 if (lenp)
484 *lenp = namelen;
485 return NULL;
486 }
487 *namep = name;
488 } else {
489 *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff));
470 }490 }
471 *namep = name;
472 }491 }
473 492
474 /* Handle realignment */493 /* Handle realignment */
475 if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&494 if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
476 fdt32_ld(&prop->len) >= 8)495 (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
477 return prop->data + 4;496 return prop->data + 4;
478 return prop->data;497 return prop->data;
479}498}
@@ -598,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, · 118 unmodified lines
598 }617 }
599 }618 }
600 619
601 if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))620 if (!can_assume(VALID_INPUT)) {
602 return -FDT_ERR_BADOFFSET;621 if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
603 else if (offset == -FDT_ERR_BADOFFSET)622 return -FDT_ERR_BADOFFSET;
604 return -FDT_ERR_BADSTRUCTURE;623 else if (offset == -FDT_ERR_BADOFFSET)
624 return -FDT_ERR_BADSTRUCTURE;
625 }
605 626
606 return offset; /* error from fdt_next_node() */627 return offset; /* error from fdt_next_node() */
607}628}
@@ -613,7 +634,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset) · 5 unmodified lines
613 634
614 err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);635 err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
615 if (err)636 if (err)
616 return (err < 0) ? err : -FDT_ERR_INTERNAL;637 return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err :
638 -FDT_ERR_INTERNAL;
617 return nodedepth;639 return nodedepth;
618}640}
619 641
@@ -833,66 +855,3 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, · 213 unmodified lines
833 855
834 return offset; /* error from fdt_next_node() */856 return offset; /* error from fdt_next_node() */
835}857}
836
837int fdt_check_full(const void *fdt, size_t bufsize)
838{
839 int err;
840 int num_memrsv;
841 int offset, nextoffset = 0;
842 uint32_t tag;
843 unsigned depth = 0;
844 const void *prop;
845 const char *propname;
846
847 if (bufsize < FDT_V1_SIZE)
848 return -FDT_ERR_TRUNCATED;
849 err = fdt_check_header(fdt);
850 if (err != 0)
851 return err;
852 if (bufsize < fdt_totalsize(fdt))
853 return -FDT_ERR_TRUNCATED;
854
855 num_memrsv = fdt_num_mem_rsv(fdt);
856 if (num_memrsv < 0)
857 return num_memrsv;
858
859 while (1) {
860 offset = nextoffset;
861 tag = fdt_next_tag(fdt, offset, &nextoffset);
862
863 if (nextoffset < 0)
864 return nextoffset;
865
866 switch (tag) {
867 case FDT_NOP:
868 break;
869
870 case FDT_END:
871 if (depth != 0)
872 return -FDT_ERR_BADSTRUCTURE;
873 return 0;
874
875 case FDT_BEGIN_NODE:
876 depth++;
877 if (depth > INT_MAX)
878 return -FDT_ERR_BADSTRUCTURE;
879 break;
880
881 case FDT_END_NODE:
882 if (depth == 0)
883 return -FDT_ERR_BADSTRUCTURE;
884 depth--;
885 break;
886
887 case FDT_PROP:
888 prop = fdt_getprop_by_offset(fdt, offset, &propname,
889 &err);
890 if (!prop)
891 return err;
892 break;
893
894 default:
895 return -FDT_ERR_INTERNAL;
896 }
897 }
898}
scripts/dtc/libfdt/fdt_rw.c+29−13
@@ -24,14 +24,16 @@ static int fdt_blocks_misordered_(const void *fdt, · 23 unmodified lines
24 24
25static int fdt_rw_probe_(void *fdt)25static int fdt_rw_probe_(void *fdt)
26{26{
27 if (can_assume(VALID_DTB))
28 return 0;
27 FDT_RO_PROBE(fdt);29 FDT_RO_PROBE(fdt);
28 30
29 if (fdt_version(fdt) < 17)31 if (!can_assume(LATEST) && fdt_version(fdt) < 17)
30 return -FDT_ERR_BADVERSION;32 return -FDT_ERR_BADVERSION;
31 if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),33 if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
32 fdt_size_dt_struct(fdt)))34 fdt_size_dt_struct(fdt)))
33 return -FDT_ERR_BADLAYOUT;35 return -FDT_ERR_BADLAYOUT;
34 if (fdt_version(fdt) > 17)36 if (!can_assume(LATEST) && fdt_version(fdt) > 17)
35 fdt_set_version(fdt, 17);37 fdt_set_version(fdt, 17);
36 38
37 return 0;39 return 0;
@@ -44,7 +46,7 @@ static int fdt_rw_probe_(void *fdt) · 6 unmodified lines
44 return err_; \46 return err_; \
45 }47 }
46 48
47static inline int fdt_data_size_(void *fdt)49static inline unsigned int fdt_data_size_(void *fdt)
48{50{
49 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);51 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
50}52}
@@ -52,15 +54,16 @@ static inline int fdt_data_size_(void *fdt) · 1 unmodified line
52static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)54static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
53{55{
54 char *p = splicepoint;56 char *p = splicepoint;
55 char *end = (char *)fdt + fdt_data_size_(fdt);57 unsigned int dsize = fdt_data_size_(fdt);
58 size_t soff = p - (char *)fdt;
56 59
57 if (((p + oldlen) < p) || ((p + oldlen) > end))60 if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize))
58 return -FDT_ERR_BADOFFSET;61 return -FDT_ERR_BADOFFSET;
59 if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))62 if ((p < (char *)fdt) || (dsize + newlen < oldlen))
60 return -FDT_ERR_BADOFFSET;63 return -FDT_ERR_BADOFFSET;
61 if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))64 if (dsize - oldlen + newlen > fdt_totalsize(fdt))
62 return -FDT_ERR_NOSPACE;65 return -FDT_ERR_NOSPACE;
63 memmove(p + newlen, p + oldlen, end - p - oldlen);66 memmove(p + newlen, p + oldlen, ((char *)fdt + dsize) - (p + oldlen));
64 return 0;67 return 0;
65}68}
66 69
@@ -112,6 +115,15 @@ static int fdt_splice_string_(void *fdt, int newlen) · 45 unmodified lines
112 return 0;115 return 0;
113}116}
114 117
118/**
119 * fdt_find_add_string_() - Find or allocate a string
120 *
121 * @fdt: pointer to the device tree to check/adjust
122 * @s: string to find/add
123 * @allocated: Set to 0 if the string was found, 1 if not found and so
124 * allocated. Ignored if can_assume(NO_ROLLBACK)
125 * @return offset of string in the string table (whether found or added)
126 */
115static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)127static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
116{128{
117 char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);129 char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
@@ -120,7 +132,8 @@ static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) · 2 unmodified lines
120 int len = strlen(s) + 1;132 int len = strlen(s) + 1;
121 int err;133 int err;
122 134
123 *allocated = 0;135 if (!can_assume(NO_ROLLBACK))
136 *allocated = 0;
124 137
125 p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);138 p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
126 if (p)139 if (p)
@@ -132,7 +145,8 @@ static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) · 5 unmodified lines
132 if (err)145 if (err)
133 return err;146 return err;
134 147
135 *allocated = 1;148 if (!can_assume(NO_ROLLBACK))
149 *allocated = 1;
136 150
137 memcpy(new, s, len);151 memcpy(new, s, len);
138 return (new - strtab);152 return (new - strtab);
@@ -206,7 +220,8 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, · 67 unmodified lines
206 220
207 err = fdt_splice_struct_(fdt, *prop, 0, proplen);221 err = fdt_splice_struct_(fdt, *prop, 0, proplen);
208 if (err) {222 if (err) {
209 if (allocated)223 /* Delete the string if we failed to add it */
224 if (!can_assume(NO_ROLLBACK) && allocated)
210 fdt_del_last_string_(fdt, name);225 fdt_del_last_string_(fdt, name);
211 return err;226 return err;
212 }227 }
@@ -411,7 +426,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) · 198 unmodified lines
411 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)426 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
412 * sizeof(struct fdt_reserve_entry);427 * sizeof(struct fdt_reserve_entry);
413 428
414 if (fdt_version(fdt) >= 17) {429 if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
415 struct_size = fdt_size_dt_struct(fdt);430 struct_size = fdt_size_dt_struct(fdt);
416 } else {431 } else {
417 struct_size = 0;432 struct_size = 0;
@@ -421,7 +436,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) · 3 unmodified lines
421 return struct_size;436 return struct_size;
422 }437 }
423 438
424 if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {439 if (can_assume(LIBFDT_ORDER) |
440 !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
425 /* no further work necessary */441 /* no further work necessary */
426 err = fdt_move(fdt, buf, bufsize);442 err = fdt_move(fdt, buf, bufsize);
427 if (err)443 if (err)
scripts/dtc/libfdt/fdt_sw.c+12−7
@@ -12,10 +12,13 @@ · 11 unmodified lines
12 12
13static int fdt_sw_probe_(void *fdt)13static int fdt_sw_probe_(void *fdt)
14{14{
15 if (fdt_magic(fdt) == FDT_MAGIC)15 if (!can_assume(VALID_INPUT)) {
16 return -FDT_ERR_BADSTATE;16 if (fdt_magic(fdt) == FDT_MAGIC)
17 else if (fdt_magic(fdt) != FDT_SW_MAGIC)17 return -FDT_ERR_BADSTATE;
18 return -FDT_ERR_BADMAGIC;18 else if (fdt_magic(fdt) != FDT_SW_MAGIC)
19 return -FDT_ERR_BADMAGIC;
20 }
21
19 return 0;22 return 0;
20}23}
21 24
@@ -38,7 +41,7 @@ static int fdt_sw_probe_memrsv_(void *fdt) · 16 unmodified lines
38 if (err)41 if (err)
39 return err;42 return err;
40 43
41 if (fdt_off_dt_strings(fdt) != 0)44 if (!can_assume(VALID_INPUT) && fdt_off_dt_strings(fdt) != 0)
42 return -FDT_ERR_BADSTATE;45 return -FDT_ERR_BADSTATE;
43 return 0;46 return 0;
44}47}
@@ -64,7 +67,8 @@ static int fdt_sw_probe_struct_(void *fdt) · 19 unmodified lines
64 if (err)67 if (err)
65 return err;68 return err;
66 69
67 if (fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))70 if (!can_assume(VALID_INPUT) &&
71 fdt_off_dt_strings(fdt) != fdt_totalsize(fdt))
68 return -FDT_ERR_BADSTATE;72 return -FDT_ERR_BADSTATE;
69 return 0;73 return 0;
70}74}
@@ -151,7 +155,8 @@ int fdt_resize(void *fdt, void *buf, int bufsize) · 80 unmodified lines
151 headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);155 headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
152 tailsize = fdt_size_dt_strings(fdt);156 tailsize = fdt_size_dt_strings(fdt);
153 157
154 if ((headsize + tailsize) > fdt_totalsize(fdt))158 if (!can_assume(VALID_DTB) &&
159 headsize + tailsize > fdt_totalsize(fdt))
155 return -FDT_ERR_INTERNAL;160 return -FDT_ERR_INTERNAL;
156 161
157 if ((headsize + tailsize) > bufsize)162 if ((headsize + tailsize) > bufsize)
scripts/dtc/libfdt/libfdt.h+5−4
@@ -266,11 +266,12 @@ fdt_set_hdr_(size_dt_struct); · 265 unmodified lines
266 * fdt_header_size - return the size of the tree's header266 * fdt_header_size - return the size of the tree's header
267 * @fdt: pointer to a flattened device tree267 * @fdt: pointer to a flattened device tree
268 */268 */
269size_t fdt_header_size(const void *fdt);
270
271/**
272 * fdt_header_size_ - internal function which takes a version number
273 */
269size_t fdt_header_size_(uint32_t version);274size_t fdt_header_size_(uint32_t version);
270static inline size_t fdt_header_size(const void *fdt)
271{
272 return fdt_header_size_(fdt_version(fdt));
273}
274 275
275/**276/**
276 * fdt_check_header - sanity check a device tree header277 * fdt_check_header - sanity check a device tree header
scripts/dtc/libfdt/libfdt_internal.h+122−0
@@ -48,4 +48,126 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) · 47 unmodified lines
48 48
49#define FDT_SW_MAGIC (~FDT_MAGIC)49#define FDT_SW_MAGIC (~FDT_MAGIC)
50 50
51/**********************************************************************/
52/* Checking controls */
53/**********************************************************************/
54
55#ifndef FDT_ASSUME_MASK
56#define FDT_ASSUME_MASK 0
57#endif
58
59/*
60 * Defines assumptions which can be enabled. Each of these can be enabled
61 * individually. For maximum safety, don't enable any assumptions!
62 *
63 * For minimal code size and no safety, use ASSUME_PERFECT at your own risk.
64 * You should have another method of validating the device tree, such as a
65 * signature or hash check before using libfdt.
66 *
67 * For situations where security is not a concern it may be safe to enable
68 * ASSUME_SANE.
69 */
70enum {
71 /*
72 * This does essentially no checks. Only the latest device-tree
73 * version is correctly handled. Inconsistencies or errors in the device
74 * tree may cause undefined behaviour or crashes. Invalid parameters
75 * passed to libfdt may do the same.
76 *
77 * If an error occurs when modifying the tree it may leave the tree in
78 * an intermediate (but valid) state. As an example, adding a property
79 * where there is insufficient space may result in the property name
80 * being added to the string table even though the property itself is
81 * not added to the struct section.
82 *
83 * Only use this if you have a fully validated device tree with
84 * the latest supported version and wish to minimise code size.
85 */
86 ASSUME_PERFECT = 0xff,
87
88 /*
89 * This assumes that the device tree is sane. i.e. header metadata
90 * and basic hierarchy are correct.
91 *
92 * With this assumption enabled, normal device trees produced by libfdt
93 * and the compiler should be handled safely. Malicious device trees and
94 * complete garbage may cause libfdt to behave badly or crash. Truncated
95 * device trees (e.g. those only partially loaded) can also cause
96 * problems.
97 *
98 * Note: Only checks that relate exclusively to the device tree itself
99 * (not the parameters passed to libfdt) are disabled by this
100 * assumption. This includes checking headers, tags and the like.
101 */
102 ASSUME_VALID_DTB = 1 << 0,
103
104 /*
105 * This builds on ASSUME_VALID_DTB and further assumes that libfdt
106 * functions are called with valid parameters, i.e. not trigger
107 * FDT_ERR_BADOFFSET or offsets that are out of bounds. It disables any
108 * extensive checking of parameters and the device tree, making various
109 * assumptions about correctness.
110 *
111 * It doesn't make sense to enable this assumption unless
112 * ASSUME_VALID_DTB is also enabled.
113 */
114 ASSUME_VALID_INPUT = 1 << 1,
115
116 /*
117 * This disables checks for device-tree version and removes all code
118 * which handles older versions.
119 *
120 * Only enable this if you know you have a device tree with the latest
121 * version.
122 */
123 ASSUME_LATEST = 1 << 2,
124
125 /*
126 * This assumes that it is OK for a failed addition to the device tree,
127 * due to lack of space or some other problem, to skip any rollback
128 * steps (such as dropping the property name from the string table).
129 * This is safe to enable in most circumstances, even though it may
130 * leave the tree in a sub-optimal state.
131 */
132 ASSUME_NO_ROLLBACK = 1 << 3,
133
134 /*
135 * This assumes that the device tree components appear in a 'convenient'
136 * order, i.e. the memory reservation block first, then the structure
137 * block and finally the string block.
138 *
139 * This order is not specified by the device-tree specification,
140 * but is expected by libfdt. The device-tree compiler always created
141 * device trees with this order.
142 *
143 * This assumption disables a check in fdt_open_into() and removes the
144 * ability to fix the problem there. This is safe if you know that the
145 * device tree is correctly ordered. See fdt_blocks_misordered_().
146 */
147 ASSUME_LIBFDT_ORDER = 1 << 4,
148
149 /*
150 * This assumes that libfdt itself does not have any internal bugs. It
151 * drops certain checks that should never be needed unless libfdt has an
152 * undiscovered bug.
153 *
154 * This can generally be considered safe to enable.
155 */
156 ASSUME_LIBFDT_FLAWLESS = 1 << 5,
157};
158
159/**
160 * can_assume_() - check if a particular assumption is enabled
161 *
162 * @mask: Mask to check (ASSUME_...)
163 * @return true if that assumption is enabled, else false
164 */
165static inline bool can_assume_(int mask)
166{
167 return FDT_ASSUME_MASK & mask;
168}
169
170/** helper macros for checking assumptions */
171#define can_assume(_assume) can_assume_(ASSUME_ ## _assume)
172
51#endif /* LIBFDT_INTERNAL_H */173#endif /* LIBFDT_INTERNAL_H */
scripts/dtc/version_gen.h+1−1
@@ -1 +1 @@
1#define DTC_VERSION "DTC 1.5.0-gc40aeb60"1#define DTC_VERSION "DTC 1.6.0-g87a656ae"