mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-08 19:11:53 +00:00
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>
This commit is contained in:
parent
6f3c2d8aa5
commit
124c255731
2 changed files with 19 additions and 1 deletions
|
@ -867,6 +867,7 @@ int fdt_check_full(const void *fdt, size_t bufsize)
|
||||||
unsigned depth = 0;
|
unsigned depth = 0;
|
||||||
const void *prop;
|
const void *prop;
|
||||||
const char *propname;
|
const char *propname;
|
||||||
|
bool expect_end = false;
|
||||||
|
|
||||||
if (bufsize < FDT_V1_SIZE)
|
if (bufsize < FDT_V1_SIZE)
|
||||||
return -FDT_ERR_TRUNCATED;
|
return -FDT_ERR_TRUNCATED;
|
||||||
|
@ -887,6 +888,10 @@ int fdt_check_full(const void *fdt, size_t bufsize)
|
||||||
if (nextoffset < 0)
|
if (nextoffset < 0)
|
||||||
return nextoffset;
|
return nextoffset;
|
||||||
|
|
||||||
|
/* If we see two root nodes, something is wrong */
|
||||||
|
if (expect_end && tag != FDT_END)
|
||||||
|
return -FDT_ERR_BADLAYOUT;
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case FDT_NOP:
|
case FDT_NOP:
|
||||||
break;
|
break;
|
||||||
|
@ -900,12 +905,24 @@ int fdt_check_full(const void *fdt, size_t bufsize)
|
||||||
depth++;
|
depth++;
|
||||||
if (depth > INT_MAX)
|
if (depth > INT_MAX)
|
||||||
return -FDT_ERR_BADSTRUCTURE;
|
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;
|
break;
|
||||||
|
|
||||||
case FDT_END_NODE:
|
case FDT_END_NODE:
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
return -FDT_ERR_BADSTRUCTURE;
|
return -FDT_ERR_BADSTRUCTURE;
|
||||||
depth--;
|
depth--;
|
||||||
|
if (depth == 0)
|
||||||
|
expect_end = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FDT_PROP:
|
case FDT_PROP:
|
||||||
|
|
|
@ -255,7 +255,8 @@ def test_vboot(u_boot_console, sha_algo, padding, sign_options, required,
|
||||||
util.run_and_log_expect_exception(
|
util.run_and_log_expect_exception(
|
||||||
cons, [fit_check_sign, '-f', efit, '-k', dtb],
|
cons, [fit_check_sign, '-f', efit, '-k', dtb],
|
||||||
1, 'Failed to verify required signature')
|
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.
|
# Try adding an @ to the kernel node name. This should be detected.
|
||||||
efit = '%stest.evilk.fit' % tmpdir
|
efit = '%stest.evilk.fit' % tmpdir
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue