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
352352 FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");
353353 } else {
354354 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");
356356 }
357357 }
358358 WARNING(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
765765 {
766766 struct property *prop;
767767 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
768+ const char *ranges = c->data;
768769
769− prop = get_property(node, "ranges");
770+ prop = get_property(node, ranges);
770771 if (!prop)
771772 return;
772773
773774 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);
775777 return;
776778 }
777779
@@ -783,23 +785,24 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, · 5 unmodified lines
783785
784786 if (prop->val.len == 0) {
785787 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 "
787789 "#address-cells (%d) differs from %s (%d)",
788− c_addr_cells, node->parent->fullpath,
790+ ranges, c_addr_cells, node->parent->fullpath,
789791 p_addr_cells);
790792 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 "
792794 "#size-cells (%d) differs from %s (%d)",
793− c_size_cells, node->parent->fullpath,
795+ ranges, c_size_cells, node->parent->fullpath,
794796 p_size_cells);
795797 } 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) "
797799 "(parent #address-cells == %d, child #address-cells == %d, "
798− "#size-cells == %d)", prop->val.len,
800+ "#size-cells == %d)", ranges, prop->val.len,
799801 p_addr_cells, c_addr_cells, c_size_cells);
800802 }
801803 }
802−WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
804+WARNING(ranges_format, check_ranges_format, "ranges", &addr_size_cells);
805+WARNING(dma_ranges_format, check_ranges_format, "dma-ranges", &addr_size_cells);
803806
804807 static const struct bus_type pci_bus = {
805808 .name = "PCI",
@@ -1780,7 +1783,7 @@ static struct check *check_table[] = { · 974 unmodified lines
17801783 &property_name_chars_strict,
17811784 &node_name_chars_strict,
17821785
1783− &addr_size_cells, &reg_format, &ranges_format,
1786+ &addr_size_cells, &reg_format, &ranges_format, &dma_ranges_format,
17841787
17851788 &unit_address_vs_reg,
17861789 &unit_address_format,
scripts/dtc/dtc-lexer.l+0−1
@@ -23,7 +23,6 @@ LINECOMMENT "//".*\n · 22 unmodified lines
2323 #include "srcpos.h"
2424 #include "dtc-parser.tab.h"
2525
26−YYLTYPE yylloc;
2726 extern bool treesource_error;
2827
2928 /* 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
1919 {
2020 uint32_t totalsize = fdt_totalsize(fdt);
2121
22+ if (can_assume(VALID_DTB))
23+ return totalsize;
24+
2225 if (fdt_magic(fdt) == FDT_MAGIC) {
2326 /* Complete tree */
24− if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
25− return -FDT_ERR_BADVERSION;
26− if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
27− return -FDT_ERR_BADVERSION;
27+ if (!can_assume(LATEST)) {
28+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
29+ return -FDT_ERR_BADVERSION;
30+ if (fdt_last_comp_version(fdt) >
31+ FDT_LAST_SUPPORTED_VERSION)
32+ return -FDT_ERR_BADVERSION;
33+ }
2834 } else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
2935 /* Unfinished sequential-write blob */
30− if (fdt_size_dt_struct(fdt) == 0)
36+ if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0)
3137 return -FDT_ERR_BADSTATE;
3238 } else {
3339 return -FDT_ERR_BADMAGIC;
@@ -70,44 +76,59 @@ size_t fdt_header_size_(uint32_t version) · 36 unmodified lines
7076 return FDT_V17_SIZE;
7177 }
7278
79+size_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+
7385 int fdt_check_header(const void *fdt)
7486 {
7587 size_t hdrsize;
7688
7789 if (fdt_magic(fdt) != FDT_MAGIC)
7890 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+ }
7999 hdrsize = fdt_header_size(fdt);
80− if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
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;
100+ if (!can_assume(VALID_DTB)) {
89101
90− /* Bounds check memrsv block */
91− if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))
92− return -FDT_ERR_TRUNCATED;
102+ if ((fdt_totalsize(fdt) < hdrsize)
103+ || (fdt_totalsize(fdt) > INT_MAX))
104+ return -FDT_ERR_TRUNCATED;
93105
94− /* Bounds check structure block */
95− if (fdt_version(fdt) < 17) {
106+ /* Bounds check memrsv block */
96107 if (!check_off_(hdrsize, fdt_totalsize(fdt),
97− fdt_off_dt_struct(fdt)))
108+ fdt_off_mem_rsvmap(fdt)))
98109 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 */
100126 if (!check_block_(hdrsize, fdt_totalsize(fdt),
101− fdt_off_dt_struct(fdt),
102− fdt_size_dt_struct(fdt)))
127+ fdt_off_dt_strings(fdt),
128+ fdt_size_dt_strings(fdt)))
103129 return -FDT_ERR_TRUNCATED;
104130 }
105131
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−
111132 return 0;
112133 }
113134
@@ -115,12 +136,13 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) · 1 unmodified line
115136 {
116137 unsigned absoffset = offset + fdt_off_dt_struct(fdt);
117138
118− if ((absoffset < offset)
119− || ((absoffset + len) < absoffset)
120− || (absoffset + len) > fdt_totalsize(fdt))
121− return NULL;
139+ if (!can_assume(VALID_INPUT))
140+ if ((absoffset < offset)
141+ || ((absoffset + len) < absoffset)
142+ || (absoffset + len) > fdt_totalsize(fdt))
143+ return NULL;
122144
123− if (fdt_version(fdt) >= 0x11)
145+ if (can_assume(LATEST) || fdt_version(fdt) >= 0x11)
124146 if (((offset + len) < offset)
125147 || ((offset + len) > fdt_size_dt_struct(fdt)))
126148 return NULL;
@@ -137,7 +159,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) · 10 unmodified lines
137159
138160 *nextoffset = -FDT_ERR_TRUNCATED;
139161 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
140− if (!tagp)
162+ if (!can_assume(VALID_DTB) && !tagp)
141163 return FDT_END; /* premature end */
142164 tag = fdt32_to_cpu(*tagp);
143165 offset += FDT_TAGSIZE;
@@ -149,18 +171,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) · 5 unmodified lines
149171 do {
150172 p = fdt_offset_ptr(fdt, offset++, 1);
151173 } while (p && (*p != '\0'));
152− if (!p)
174+ if (!can_assume(VALID_DTB) && !p)
153175 return FDT_END; /* premature end */
154176 break;
155177
156178 case FDT_PROP:
157179 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
158− if (!lenp)
180+ if (!can_assume(VALID_DTB) && !lenp)
159181 return FDT_END; /* premature end */
160182 /* skip-name offset, length and value */
161183 offset += sizeof(struct fdt_property) - FDT_TAGSIZE
162184 + 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 &&
164187 ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
165188 offset += 4;
166189 break;
@@ -183,6 +206,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) · 16 unmodified lines
183206
184207 int fdt_check_node_offset_(const void *fdt, int offset)
185208 {
209+ if (can_assume(VALID_INPUT))
210+ return offset;
186211 if ((offset < 0) || (offset % FDT_TAGSIZE)
187212 || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
188213 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
3333
3434 const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
3535 {
36− int32_t totalsize = fdt_ro_probe_(fdt);
37− uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);
36+ int32_t totalsize;
37+ uint32_t absoffset;
3838 size_t len;
3939 int err;
4040 const char *s, *n;
4141
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);
4250 err = totalsize;
4351 if (totalsize < 0)
4452 goto fail;
4553
4654 err = -FDT_ERR_BADOFFSET;
55+ absoffset = stroffset + fdt_off_dt_strings(fdt);
4756 if (absoffset >= totalsize)
4857 goto fail;
4958 len = totalsize - absoffset;
@@ -51,7 +60,7 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) · 1 unmodified line
5160 if (fdt_magic(fdt) == FDT_MAGIC) {
5261 if (stroffset < 0)
5362 goto fail;
54− if (fdt_version(fdt) >= 17) {
63+ if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
5564 if (stroffset >= fdt_size_dt_strings(fdt))
5665 goto fail;
5766 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
151160 int offset = n * sizeof(struct fdt_reserve_entry);
152161 int absoffset = fdt_off_mem_rsvmap(fdt) + offset;
153162
154− if (absoffset < fdt_off_mem_rsvmap(fdt))
155− return NULL;
156− if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))
157− return NULL;
163+ if (!can_assume(VALID_INPUT)) {
164+ if (absoffset < fdt_off_mem_rsvmap(fdt))
165+ return NULL;
166+ if (absoffset > fdt_totalsize(fdt) -
167+ sizeof(struct fdt_reserve_entry))
168+ return NULL;
169+ }
158170 return fdt_mem_rsv_(fdt, n);
159171 }
160172
@@ -164,7 +176,7 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) · 3 unmodified lines
164176
165177 FDT_RO_PROBE(fdt);
166178 re = fdt_mem_rsv(fdt, n);
167− if (!re)
179+ if (!can_assume(VALID_INPUT) && !re)
168180 return -FDT_ERR_BADOFFSET;
169181
170182 *address = fdt64_ld(&re->address);
@@ -295,7 +307,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) · 124 unmodified lines
295307
296308 nameptr = nh->name;
297309
298− if (fdt_version(fdt) < 0x10) {
310+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
299311 /*
300312 * For old FDT versions, match the naming conventions of V16:
301313 * 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
346358 int err;
347359 const struct fdt_property *prop;
348360
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) {
350363 if (lenp)
351364 *lenp = err;
352365 return NULL;
@@ -367,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, · 14 unmodified lines
367380 /* Prior to version 16, properties may need realignment
368381 * and this API does not work. fdt_getprop_*() will, however. */
369382
370− if (fdt_version(fdt) < 0x10) {
383+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
371384 if (lenp)
372385 *lenp = -FDT_ERR_BADVERSION;
373386 return NULL;
@@ -388,7 +401,8 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, · 14 unmodified lines
388401 (offset = fdt_next_property_offset(fdt, offset))) {
389402 const struct fdt_property *prop;
390403
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) {
392406 offset = -FDT_ERR_INTERNAL;
393407 break;
394408 }
@@ -413,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, · 18 unmodified lines
413427 {
414428 /* Prior to version 16, properties may need realignment
415429 * 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) {
417431 if (lenp)
418432 *lenp = -FDT_ERR_BADVERSION;
419433 return NULL;
@@ -444,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, · 24 unmodified lines
444458 return NULL;
445459
446460 /* Handle realignment */
447− if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&
448− fdt32_ld(&prop->len) >= 8)
461+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
462+ (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
449463 return prop->data + 4;
450464 return prop->data;
451465 }
@@ -461,19 +475,24 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, · 9 unmodified lines
461475 if (namep) {
462476 const char *name;
463477 int namelen;
464− name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
465− &namelen);
466− if (!name) {
467− if (lenp)
468− *lenp = namelen;
469− return NULL;
478+
479+ if (!can_assume(VALID_INPUT)) {
480+ name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
481+ &namelen);
482+ if (!name) {
483+ if (lenp)
484+ *lenp = namelen;
485+ return NULL;
486+ }
487+ *namep = name;
488+ } else {
489+ *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff));
470490 }
471− *namep = name;
472491 }
473492
474493 /* Handle realignment */
475− if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&
476− fdt32_ld(&prop->len) >= 8)
494+ if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
495+ (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
477496 return prop->data + 4;
478497 return prop->data;
479498 }
@@ -598,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, · 118 unmodified lines
598617 }
599618 }
600619
601− if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
602− return -FDT_ERR_BADOFFSET;
603− else if (offset == -FDT_ERR_BADOFFSET)
604− return -FDT_ERR_BADSTRUCTURE;
620+ if (!can_assume(VALID_INPUT)) {
621+ if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
622+ return -FDT_ERR_BADOFFSET;
623+ else if (offset == -FDT_ERR_BADOFFSET)
624+ return -FDT_ERR_BADSTRUCTURE;
625+ }
605626
606627 return offset; /* error from fdt_next_node() */
607628 }
@@ -613,7 +634,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset) · 5 unmodified lines
613634
614635 err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
615636 if (err)
616− return (err < 0) ? err : -FDT_ERR_INTERNAL;
637+ return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err :
638+ -FDT_ERR_INTERNAL;
617639 return nodedepth;
618640 }
619641
@@ -833,66 +855,3 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, · 213 unmodified lines
833855
834856 return offset; /* error from fdt_next_node() */
835857 }
836−
837−int 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
2424
2525 static int fdt_rw_probe_(void *fdt)
2626 {
27+ if (can_assume(VALID_DTB))
28+ return 0;
2729 FDT_RO_PROBE(fdt);
2830
29− if (fdt_version(fdt) < 17)
31+ if (!can_assume(LATEST) && fdt_version(fdt) < 17)
3032 return -FDT_ERR_BADVERSION;
3133 if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
3234 fdt_size_dt_struct(fdt)))
3335 return -FDT_ERR_BADLAYOUT;
34− if (fdt_version(fdt) > 17)
36+ if (!can_assume(LATEST) && fdt_version(fdt) > 17)
3537 fdt_set_version(fdt, 17);
3638
3739 return 0;
@@ -44,7 +46,7 @@ static int fdt_rw_probe_(void *fdt) · 6 unmodified lines
4446 return err_; \
4547 }
4648
47−static inline int fdt_data_size_(void *fdt)
49+static inline unsigned int fdt_data_size_(void *fdt)
4850 {
4951 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
5052 }
@@ -52,15 +54,16 @@ static inline int fdt_data_size_(void *fdt) · 1 unmodified line
5254 static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
5355 {
5456 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;
5659
57− if (((p + oldlen) < p) || ((p + oldlen) > end))
60+ if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize))
5861 return -FDT_ERR_BADOFFSET;
59− if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
62+ if ((p < (char *)fdt) || (dsize + newlen < oldlen))
6063 return -FDT_ERR_BADOFFSET;
61− if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
64+ if (dsize - oldlen + newlen > fdt_totalsize(fdt))
6265 return -FDT_ERR_NOSPACE;
63− memmove(p + newlen, p + oldlen, end - p - oldlen);
66+ memmove(p + newlen, p + oldlen, ((char *)fdt + dsize) - (p + oldlen));
6467 return 0;
6568 }
6669
@@ -112,6 +115,15 @@ static int fdt_splice_string_(void *fdt, int newlen) · 45 unmodified lines
112115 return 0;
113116 }
114117
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+ */
115127 static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
116128 {
117129 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
120132 int len = strlen(s) + 1;
121133 int err;
122134
123− *allocated = 0;
135+ if (!can_assume(NO_ROLLBACK))
136+ *allocated = 0;
124137
125138 p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
126139 if (p)
@@ -132,7 +145,8 @@ static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) · 5 unmodified lines
132145 if (err)
133146 return err;
134147
135− *allocated = 1;
148+ if (!can_assume(NO_ROLLBACK))
149+ *allocated = 1;
136150
137151 memcpy(new, s, len);
138152 return (new - strtab);
@@ -206,7 +220,8 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, · 67 unmodified lines
206220
207221 err = fdt_splice_struct_(fdt, *prop, 0, proplen);
208222 if (err) {
209− if (allocated)
223+ /* Delete the string if we failed to add it */
224+ if (!can_assume(NO_ROLLBACK) && allocated)
210225 fdt_del_last_string_(fdt, name);
211226 return err;
212227 }
@@ -411,7 +426,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) · 198 unmodified lines
411426 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
412427 * sizeof(struct fdt_reserve_entry);
413428
414− if (fdt_version(fdt) >= 17) {
429+ if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
415430 struct_size = fdt_size_dt_struct(fdt);
416431 } else {
417432 struct_size = 0;
@@ -421,7 +436,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) · 3 unmodified lines
421436 return struct_size;
422437 }
423438
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)) {
425441 /* no further work necessary */
426442 err = fdt_move(fdt, buf, bufsize);
427443 if (err)
scripts/dtc/libfdt/fdt_sw.c+12−7
@@ -12,10 +12,13 @@ · 11 unmodified lines
1212
1313 static int fdt_sw_probe_(void *fdt)
1414 {
15− if (fdt_magic(fdt) == FDT_MAGIC)
16− return -FDT_ERR_BADSTATE;
17− else if (fdt_magic(fdt) != FDT_SW_MAGIC)
18− return -FDT_ERR_BADMAGIC;
15+ if (!can_assume(VALID_INPUT)) {
16+ if (fdt_magic(fdt) == FDT_MAGIC)
17+ return -FDT_ERR_BADSTATE;
18+ else if (fdt_magic(fdt) != FDT_SW_MAGIC)
19+ return -FDT_ERR_BADMAGIC;
20+ }
21+
1922 return 0;
2023 }
2124
@@ -38,7 +41,7 @@ static int fdt_sw_probe_memrsv_(void *fdt) · 16 unmodified lines
3841 if (err)
3942 return err;
4043
41− if (fdt_off_dt_strings(fdt) != 0)
44+ if (!can_assume(VALID_INPUT) && fdt_off_dt_strings(fdt) != 0)
4245 return -FDT_ERR_BADSTATE;
4346 return 0;
4447 }
@@ -64,7 +67,8 @@ static int fdt_sw_probe_struct_(void *fdt) · 19 unmodified lines
6467 if (err)
6568 return err;
6669
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))
6872 return -FDT_ERR_BADSTATE;
6973 return 0;
7074 }
@@ -151,7 +155,8 @@ int fdt_resize(void *fdt, void *buf, int bufsize) · 80 unmodified lines
151155 headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
152156 tailsize = fdt_size_dt_strings(fdt);
153157
154− if ((headsize + tailsize) > fdt_totalsize(fdt))
158+ if (!can_assume(VALID_DTB) &&
159+ headsize + tailsize > fdt_totalsize(fdt))
155160 return -FDT_ERR_INTERNAL;
156161
157162 if ((headsize + tailsize) > bufsize)
scripts/dtc/libfdt/libfdt.h+5−4
@@ -266,11 +266,12 @@ fdt_set_hdr_(size_dt_struct); · 265 unmodified lines
266266 * fdt_header_size - return the size of the tree's header
267267 * @fdt: pointer to a flattened device tree
268268 */
269+size_t fdt_header_size(const void *fdt);
270+
271+/**
272+ * fdt_header_size_ - internal function which takes a version number
273+ */
269274 size_t fdt_header_size_(uint32_t version);
270−static inline size_t fdt_header_size(const void *fdt)
271−{
272− return fdt_header_size_(fdt_version(fdt));
273−}
274275
275276 /**
276277 * 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
4848
4949 #define FDT_SW_MAGIC (~FDT_MAGIC)
5050
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+ */
70+enum {
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+ */
165+static 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+
51173 #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"