From: Simon Glass <s...@chromium.org>

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 <s...@chromium.org>
Message-Id: <20200220214557.176528-5-...@chromium.org>
Signed-off-by: David Gibson <da...@gibson.dropbear.id.au>
---
 cpukit/dtc/libfdt/fdt.c    | 11 ++++++---
 cpukit/dtc/libfdt/fdt_ro.c | 61 +++++++++++++++++++++++++++++++---------------
 2 files changed, 48 insertions(+), 24 deletions(-)

diff --git a/cpukit/dtc/libfdt/fdt.c b/cpukit/dtc/libfdt/fdt.c
index d4daf6096c..0dabb920ad 100644
--- a/cpukit/dtc/libfdt/fdt.c
+++ b/cpukit/dtc/libfdt/fdt.c
@@ -129,10 +129,11 @@ const void *fdt_offset_ptr(const void *fdt, int offset, 
unsigned int len)
 {
        unsigned absoffset = offset + fdt_off_dt_struct(fdt);
 
-       if ((absoffset < offset)
-           || ((absoffset + len) < absoffset)
-           || (absoffset + len) > fdt_totalsize(fdt))
-               return NULL;
+       if (!can_assume(VALID_INPUT))
+               if ((absoffset < offset)
+                   || ((absoffset + len) < absoffset)
+                   || (absoffset + len) > fdt_totalsize(fdt))
+                       return NULL;
 
        if (fdt_version(fdt) >= 0x11)
                if (((offset + len) < offset)
@@ -197,6 +198,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int 
*nextoffset)
 
 int fdt_check_node_offset_(const void *fdt, int offset)
 {
+       if (can_assume(VALID_INPUT))
+               return offset;
        if ((offset < 0) || (offset % FDT_TAGSIZE)
            || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
                return -FDT_ERR_BADOFFSET;
diff --git a/cpukit/dtc/libfdt/fdt_ro.c b/cpukit/dtc/libfdt/fdt_ro.c
index 4c26fbeb8d..9c325591ae 100644
--- a/cpukit/dtc/libfdt/fdt_ro.c
+++ b/cpukit/dtc/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;
 }
 
-- 
2.16.4

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to