summaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2021-02-15 17:08:11 -0700
committerTom Rini <trini@konsulko.com>2021-02-15 22:31:53 -0500
commit124c255731c76a2b09587378b2bcce561bcd3f2d (patch)
tree03e9ce18107e891c917d48b177560370fc2f6708 /scripts
parent6f3c2d8aa5e6cbd80b5e869bbbddecb66c329d01 (diff)
downloadu-boot-124c255731c76a2b09587378b2bcce561bcd3f2d.tar.gz
u-boot-124c255731c76a2b09587378b2bcce561bcd3f2d.tar.xz
u-boot-124c255731c76a2b09587378b2bcce561bcd3f2d.zip
libfdt: Check for multiple/invalid root nodes
It is possible to construct a devicetree blob with multiple root nodes. Update fdt_check_full() to check for this, along with a root node with an invalid name. CVE-2021-27097 Signed-off-by: Simon Glass <sjg@chromium.org> Reported-by: Bruce Monroe <bruce.monroe@intel.com> Reported-by: Arie Haenel <arie.haenel@intel.com> Reported-by: Julien Lenoir <julien.lenoir@intel.com>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/dtc/libfdt/fdt_ro.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index d984bab036..efe7efe921 100644
--- a/scripts/dtc/libfdt/fdt_ro.c
+++ b/scripts/dtc/libfdt/fdt_ro.c
@@ -867,6 +867,7 @@ int fdt_check_full(const void *fdt, size_t bufsize)
unsigned depth = 0;
const void *prop;
const char *propname;
+ bool expect_end = false;
if (bufsize < FDT_V1_SIZE)
return -FDT_ERR_TRUNCATED;
@@ -887,6 +888,10 @@ int fdt_check_full(const void *fdt, size_t bufsize)
if (nextoffset < 0)
return nextoffset;
+ /* If we see two root nodes, something is wrong */
+ if (expect_end && tag != FDT_END)
+ return -FDT_ERR_BADLAYOUT;
+
switch (tag) {
case FDT_NOP:
break;
@@ -900,12 +905,24 @@ int fdt_check_full(const void *fdt, size_t bufsize)
depth++;
if (depth > INT_MAX)
return -FDT_ERR_BADSTRUCTURE;
+
+ /* The root node must have an empty name */
+ if (depth == 1) {
+ const char *name;
+ int len;
+
+ name = fdt_get_name(fdt, offset, &len);
+ if (*name || len)
+ return -FDT_ERR_BADLAYOUT;
+ }
break;
case FDT_END_NODE:
if (depth == 0)
return -FDT_ERR_BADSTRUCTURE;
depth--;
+ if (depth == 0)
+ expect_end = true;
break;
case FDT_PROP: