diff options
author | Simon Glass <sjg@chromium.org> | 2020-02-20 14:45:53 -0700 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2020-02-24 13:38:44 +1100 |
commit | 77563ae72b7c3349008e712669253f6c54b752a7 (patch) | |
tree | 986ad130bcd63bf932d220586aac34e634b2c3d9 /libfdt/fdt_ro.c | |
parent | 57bc6327b80bc95bee9fc5f07d4fc83186a8f167 (diff) | |
download | dtc-77563ae72b7c3349008e712669253f6c54b752a7.zip dtc-77563ae72b7c3349008e712669253f6c54b752a7.tar.gz dtc-77563ae72b7c3349008e712669253f6c54b752a7.tar.bz2 |
libfdt: Add support for disabling sanity checks
Allow enabling ASSUME_VALID_INPUT to disable sanity checks on the device
tree and the parameters to libfdt. This assumption covers that cases where
the problem could be with either.
Signed-off-by: Simon Glass <sjg@chromium.org>
Message-Id: <20200220214557.176528-5-sjg@chromium.org>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'libfdt/fdt_ro.c')
-rw-r--r-- | libfdt/fdt_ro.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 4c26fbe..9c32559 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -33,17 +33,26 @@ static int fdt_nodename_eq_(const void *fdt, int offset, const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) { - int32_t totalsize = fdt_ro_probe_(fdt); - uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt); + int32_t totalsize; + uint32_t absoffset; size_t len; int err; const char *s, *n; + if (can_assume(VALID_INPUT)) { + s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; + + if (lenp) + *lenp = strlen(s); + return s; + } + totalsize = fdt_ro_probe_(fdt); err = totalsize; if (totalsize < 0) goto fail; err = -FDT_ERR_BADOFFSET; + absoffset = stroffset + fdt_off_dt_strings(fdt); if (absoffset >= totalsize) goto fail; len = totalsize - absoffset; @@ -151,10 +160,13 @@ static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) int offset = n * sizeof(struct fdt_reserve_entry); int absoffset = fdt_off_mem_rsvmap(fdt) + offset; - if (absoffset < fdt_off_mem_rsvmap(fdt)) - return NULL; - if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry)) - return NULL; + if (!can_assume(VALID_INPUT)) { + if (absoffset < fdt_off_mem_rsvmap(fdt)) + return NULL; + if (absoffset > fdt_totalsize(fdt) - + sizeof(struct fdt_reserve_entry)) + return NULL; + } return fdt_mem_rsv_(fdt, n); } @@ -164,7 +176,7 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) FDT_RO_PROBE(fdt); re = fdt_mem_rsv(fdt, n); - if (!re) + if (!can_assume(VALID_INPUT) && !re) return -FDT_ERR_BADOFFSET; *address = fdt64_ld(&re->address); @@ -346,7 +358,8 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, int err; const struct fdt_property *prop; - if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { + if (!can_assume(VALID_INPUT) && + (err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; @@ -462,14 +475,19 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, if (namep) { const char *name; int namelen; - name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), - &namelen); - if (!name) { - if (lenp) - *lenp = namelen; - return NULL; + + if (!can_assume(VALID_INPUT)) { + name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), + &namelen); + if (!name) { + if (lenp) + *lenp = namelen; + return NULL; + } + *namep = name; + } else { + *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff)); } - *namep = name; } /* Handle realignment */ @@ -599,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, } } - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; + if (!can_assume(VALID_INPUT)) { + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + } return offset; /* error from fdt_next_node() */ } @@ -614,7 +634,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset) err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); if (err) - return (err < 0) ? err : -FDT_ERR_INTERNAL; + return (can_assume(VALID_INPUT) || err < 0) ? err : + -FDT_ERR_INTERNAL; return nodedepth; } |