| From 124c255731c76a2b09587378b2bcce561bcd3f2d Mon Sep 17 00:00:00 2001 |
| From: Simon Glass <sjg@chromium.org> |
| Date: Mon, 15 Feb 2021 17:08:11 -0700 |
| Subject: [PATCH] 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> |
| |
| CVE: CVE-2021-27097 |
| Upstream-Status: Backport[https://github.com/u-boot/u-boot/commit/124c255731c76a2b09587378b2bcce561bcd3f2d] |
| Signed-off-by: Scott Murray <scott.murray@konsulko.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 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: |