]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
libfdt: Check for multiple/invalid root nodes
authorSimon Glass <sjg@chromium.org>
Tue, 16 Feb 2021 00:08:11 +0000 (17:08 -0700)
committerTom Rini <trini@konsulko.com>
Tue, 16 Feb 2021 03:31:53 +0000 (22:31 -0500)
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>
scripts/dtc/libfdt/fdt_ro.c
test/py/tests/test_vboot.py

index d984bab036b59b365328a7d46fd1b424bee4dc89..efe7efe92115117db7ff65ece031b175c3110ebc 100644 (file)
@@ -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:
index 9cdc290b9fc047b086c0f14b7566a2a4ad421b87..22e8fc10d83bea1638bf8ebc6c0ad8cc20efdd2b 100644 (file)
@@ -255,7 +255,8 @@ def test_vboot(u_boot_console, sha_algo, padding, sign_options, required,
             util.run_and_log_expect_exception(
                 cons, [fit_check_sign, '-f', efit, '-k', dtb],
                 1, 'Failed to verify required signature')
-            run_bootm(sha_algo, 'evil fakeroot', 'Bad Data Hash', False, efit)
+            run_bootm(sha_algo, 'evil fakeroot', 'Bad FIT kernel image format',
+                      False, efit)
 
             # Try adding an @ to the kernel node name. This should be detected.
             efit = '%stest.evilk.fit' % tmpdir