From: David Gibson <da...@gibson.dropbear.id.au>

This new function implements a complete and thorough check of an fdt blob's
structure.  Given a buffer containing an fdt, it should return 0 only if
the fdt within is structurally sound in all regards.  It doesn't check
anything about the blob's contents (i.e. the actual values of the nodes and
properties), of course.

Signed-off-by: David Gibson <da...@gibson.dropbear.id.au>
Tested-by: Alexey Kardashevskiy <a...@ozlabs.ru>
Reviewed-by: Alexey Kardashevskiy <a...@ozlabs.ru>
Reviewed-by: Simon Glass <s...@chromium.org>
---
 cpukit/dtc/libfdt/fdt_ro.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++
 cpukit/include/libfdt.h    |  2 ++
 2 files changed, 65 insertions(+)

diff --git a/cpukit/dtc/libfdt/fdt_ro.c b/cpukit/dtc/libfdt/fdt_ro.c
index c74b9629af..4ba7c93313 100644
--- a/cpukit/dtc/libfdt/fdt_ro.c
+++ b/cpukit/dtc/libfdt/fdt_ro.c
@@ -857,3 +857,66 @@ int fdt_node_offset_by_compatible(const void *fdt, int 
startoffset,
 
        return offset; /* error from fdt_next_node() */
 }
+
+int fdt_check_full(const void *fdt, size_t bufsize)
+{
+       int err;
+       int num_memrsv;
+       int offset, nextoffset = 0;
+       uint32_t tag;
+       unsigned depth = 0;
+       const void *prop;
+       const char *propname;
+
+       if (bufsize < FDT_V1_SIZE)
+               return -FDT_ERR_TRUNCATED;
+       err = fdt_check_header(fdt);
+       if (err != 0)
+               return err;
+       if (bufsize < fdt_totalsize(fdt))
+               return -FDT_ERR_TRUNCATED;
+
+       num_memrsv = fdt_num_mem_rsv(fdt);
+       if (num_memrsv < 0)
+               return num_memrsv;
+
+       while (1) {
+               offset = nextoffset;
+               tag = fdt_next_tag(fdt, offset, &nextoffset);
+
+               if (nextoffset < 0)
+                       return nextoffset;
+
+               switch (tag) {
+               case FDT_NOP:
+                       break;
+
+               case FDT_END:
+                       if (depth != 0)
+                               return -FDT_ERR_BADSTRUCTURE;
+                       return 0;
+
+               case FDT_BEGIN_NODE:
+                       depth++;
+                       if (depth > INT_MAX)
+                               return -FDT_ERR_BADSTRUCTURE;
+                       break;
+
+               case FDT_END_NODE:
+                       if (depth == 0)
+                               return -FDT_ERR_BADSTRUCTURE;
+                       depth--;
+                       break;
+
+               case FDT_PROP:
+                       prop = fdt_getprop_by_offset(fdt, offset, &propname,
+                                                    &err);
+                       if (!prop)
+                               return err;
+                       break;
+
+               default:
+                       return -FDT_ERR_INTERNAL;
+               }
+       }
+}
diff --git a/cpukit/include/libfdt.h b/cpukit/include/libfdt.h
index b81d046e54..79e4d82619 100644
--- a/cpukit/include/libfdt.h
+++ b/cpukit/include/libfdt.h
@@ -298,6 +298,8 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
 /* Read-only functions                                                */
 /**********************************************************************/
 
+int fdt_check_full(const void *fdt, size_t bufsize);
+
 /**
  * fdt_get_string - retrieve a string from the strings block of a device tree
  * @fdt: pointer to the device tree blob
-- 
2.13.7

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

Reply via email to