diff options
author | Simon Glass <sjg@chromium.org> | 2021-02-15 17:08:11 -0700 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-02-15 22:31:53 -0500 |
commit | 124c255731c76a2b09587378b2bcce561bcd3f2d (patch) | |
tree | 03e9ce18107e891c917d48b177560370fc2f6708 /scripts/dtc | |
parent | 6f3c2d8aa5e6cbd80b5e869bbbddecb66c329d01 (diff) | |
download | u-boot-124c255731c76a2b09587378b2bcce561bcd3f2d.tar.gz u-boot-124c255731c76a2b09587378b2bcce561bcd3f2d.tar.bz2 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/dtc')
-rw-r--r-- | scripts/dtc/libfdt/fdt_ro.c | 17 |
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: |