[PATCH 7/8] libfdt: Check for multiple/invalid root nodes
Simon Glass
sjg at chromium.org
Tue Feb 16 01:08:11 CET 2021
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 at chromium.org>
Reported-by: Bruce Monroe <bruce.monroe at intel.com>
Reported-by: Arie Haenel <arie.haenel at intel.com>
Reported-by: Julien Lenoir <julien.lenoir at intel.com>
---
scripts/dtc/libfdt/fdt_ro.c | 17 +++++++++++++++++
test/py/tests/test_vboot.py | 3 ++-
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c
index d984bab036b..efe7efe9211 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:
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 9cdc290b9fc..22e8fc10d83 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -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
--
2.30.0.478.g8a0d178c01-goog
More information about the U-Boot
mailing list