libfdt: Check that the root-node name is empty
The root node is supposed to have an empty name, but at present this is not checked. The behaviour of such a tree is not well defined. Most software rightly assumes that the root node is at offset 0 and does not check the name. This oddity was discovered as part of a security investigation into U-Boot verified boot. Add a check for this to fdt_check_full(). Signed-off-by: Simon Glass <sjg@chromium.org> Reported-by: Arie Haenel <arie.haenel@intel.com> Reported-by: Julien Lenoir <julien.lenoir@intel.com> Message-Id: <20210323010410.3222701-2-sjg@chromium.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
4ca61f84dc
commit
a2def54799
6 changed files with 30 additions and 3 deletions
|
@ -59,6 +59,16 @@ 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_BADSTRUCTURE;
|
||||
}
|
||||
break;
|
||||
|
||||
case FDT_END_NODE:
|
||||
|
|
|
@ -33,7 +33,7 @@ LIB_TESTS_L = get_mem_rsv \
|
|||
LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)
|
||||
|
||||
LIBTREE_TESTS_L = truncated_property truncated_string truncated_memrsv \
|
||||
two_roots
|
||||
two_roots named_root
|
||||
|
||||
LIBTREE_TESTS = $(LIBTREE_TESTS_L:%=$(TESTS_PREFIX)%)
|
||||
|
||||
|
|
|
@ -24,7 +24,8 @@ static struct {
|
|||
TREE(ovf_size_strings),
|
||||
TREE(truncated_property), TREE(truncated_string),
|
||||
TREE(truncated_memrsv),
|
||||
TREE(two_roots)
|
||||
TREE(two_roots),
|
||||
TREE(named_root)
|
||||
};
|
||||
|
||||
#define NUM_TREES (sizeof(trees) / sizeof(trees[0]))
|
||||
|
|
|
@ -518,7 +518,7 @@ libfdt_tests () {
|
|||
run_test check_full $good
|
||||
done
|
||||
for bad in truncated_property.dtb truncated_string.dtb \
|
||||
truncated_memrsv.dtb two_roots.dtb; do
|
||||
truncated_memrsv.dtb two_roots.dtb named_root.dtb; do
|
||||
run_test check_full -n $bad
|
||||
done
|
||||
}
|
||||
|
|
|
@ -56,4 +56,5 @@ extern struct fdt_header ovf_size_strings;
|
|||
extern struct fdt_header truncated_string;
|
||||
extern struct fdt_header truncated_memrsv;
|
||||
extern struct fdt_header two_roots;
|
||||
extern struct fdt_header named_root;
|
||||
#endif /* ! __ASSEMBLY */
|
||||
|
|
|
@ -298,3 +298,18 @@ two_roots_strings_end:
|
|||
|
||||
two_roots_end:
|
||||
|
||||
|
||||
/* root node with a non-empty name */
|
||||
TREE_HDR(named_root)
|
||||
EMPTY_RSVMAP(named_root)
|
||||
|
||||
named_root_struct:
|
||||
BEGIN_NODE("fake")
|
||||
END_NODE
|
||||
FDTLONG(FDT_END)
|
||||
named_root_struct_end:
|
||||
|
||||
named_root_strings:
|
||||
named_root_strings_end:
|
||||
|
||||
named_root_end:
|
||||
|
|
Loading…
Reference in a new issue