libfdt: Allow exclusion of fdt_check_full()
This function is used to perform a full check of the device tree. Allow it to be excluded if all assumptions are enabled. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Message-Id: <20200220214557.176528-9-sjg@chromium.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
committed by
David Gibson
parent
f270f45fd5
commit
0f61c72ded
@@ -8,7 +8,7 @@ LIBFDT_soname = libfdt.$(SHAREDLIB_EXT).1
|
|||||||
LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
|
LIBFDT_INCLUDES = fdt.h libfdt.h libfdt_env.h
|
||||||
LIBFDT_VERSION = version.lds
|
LIBFDT_VERSION = version.lds
|
||||||
LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
|
LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \
|
||||||
fdt_addresses.c fdt_overlay.c
|
fdt_addresses.c fdt_overlay.c fdt_check.c
|
||||||
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
|
LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
|
||||||
LIBFDT_LIB = libfdt-$(DTC_VERSION).$(SHAREDLIB_EXT)
|
LIBFDT_LIB = libfdt-$(DTC_VERSION).$(SHAREDLIB_EXT)
|
||||||
|
|
||||||
|
|||||||
74
libfdt/fdt_check.c
Normal file
74
libfdt/fdt_check.c
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
|
||||||
|
/*
|
||||||
|
* libfdt - Flat Device Tree manipulation
|
||||||
|
* Copyright (C) 2006 David Gibson, IBM Corporation.
|
||||||
|
*/
|
||||||
|
#include "libfdt_env.h"
|
||||||
|
|
||||||
|
#include <fdt.h>
|
||||||
|
#include <libfdt.h>
|
||||||
|
|
||||||
|
#include "libfdt_internal.h"
|
||||||
|
|
||||||
|
int fdt_check_full(const void *fdt, size_t bufsize)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
int num_memrsv;
|
||||||
|
int offset, nextoffset = 0;
|
||||||
|
uint32_t tag;
|
||||||
|
unsigned int depth = 0;
|
||||||
|
const void *prop;
|
||||||
|
const char *propname;
|
||||||
|
|
||||||
|
if (bufsize < FDT_V1_SIZE)
|
||||||
|
return -FDT_ERR_TRUNCATED;
|
||||||
|
err = fdt_check_header(fdt);
|
||||||
|
if (err != 0)
|
||||||
|
return err;
|
||||||
|
if (bufsize < fdt_totalsize(fdt))
|
||||||
|
return -FDT_ERR_TRUNCATED;
|
||||||
|
|
||||||
|
num_memrsv = fdt_num_mem_rsv(fdt);
|
||||||
|
if (num_memrsv < 0)
|
||||||
|
return num_memrsv;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
offset = nextoffset;
|
||||||
|
tag = fdt_next_tag(fdt, offset, &nextoffset);
|
||||||
|
|
||||||
|
if (nextoffset < 0)
|
||||||
|
return nextoffset;
|
||||||
|
|
||||||
|
switch (tag) {
|
||||||
|
case FDT_NOP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FDT_END:
|
||||||
|
if (depth != 0)
|
||||||
|
return -FDT_ERR_BADSTRUCTURE;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case FDT_BEGIN_NODE:
|
||||||
|
depth++;
|
||||||
|
if (depth > INT_MAX)
|
||||||
|
return -FDT_ERR_BADSTRUCTURE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FDT_END_NODE:
|
||||||
|
if (depth == 0)
|
||||||
|
return -FDT_ERR_BADSTRUCTURE;
|
||||||
|
depth--;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FDT_PROP:
|
||||||
|
prop = fdt_getprop_by_offset(fdt, offset, &propname,
|
||||||
|
&err);
|
||||||
|
if (!prop)
|
||||||
|
return err;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -FDT_ERR_INTERNAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -855,66 +855,3 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
|
|||||||
|
|
||||||
return offset; /* error from fdt_next_node() */
|
return offset; /* error from fdt_next_node() */
|
||||||
}
|
}
|
||||||
|
|
||||||
int fdt_check_full(const void *fdt, size_t bufsize)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
int num_memrsv;
|
|
||||||
int offset, nextoffset = 0;
|
|
||||||
uint32_t tag;
|
|
||||||
unsigned depth = 0;
|
|
||||||
const void *prop;
|
|
||||||
const char *propname;
|
|
||||||
|
|
||||||
if (bufsize < FDT_V1_SIZE)
|
|
||||||
return -FDT_ERR_TRUNCATED;
|
|
||||||
err = fdt_check_header(fdt);
|
|
||||||
if (err != 0)
|
|
||||||
return err;
|
|
||||||
if (bufsize < fdt_totalsize(fdt))
|
|
||||||
return -FDT_ERR_TRUNCATED;
|
|
||||||
|
|
||||||
num_memrsv = fdt_num_mem_rsv(fdt);
|
|
||||||
if (num_memrsv < 0)
|
|
||||||
return num_memrsv;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
offset = nextoffset;
|
|
||||||
tag = fdt_next_tag(fdt, offset, &nextoffset);
|
|
||||||
|
|
||||||
if (nextoffset < 0)
|
|
||||||
return nextoffset;
|
|
||||||
|
|
||||||
switch (tag) {
|
|
||||||
case FDT_NOP:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FDT_END:
|
|
||||||
if (depth != 0)
|
|
||||||
return -FDT_ERR_BADSTRUCTURE;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case FDT_BEGIN_NODE:
|
|
||||||
depth++;
|
|
||||||
if (depth > INT_MAX)
|
|
||||||
return -FDT_ERR_BADSTRUCTURE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FDT_END_NODE:
|
|
||||||
if (depth == 0)
|
|
||||||
return -FDT_ERR_BADSTRUCTURE;
|
|
||||||
depth--;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FDT_PROP:
|
|
||||||
prop = fdt_getprop_by_offset(fdt, offset, &propname,
|
|
||||||
&err);
|
|
||||||
if (!prop)
|
|
||||||
return err;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return -FDT_ERR_INTERNAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user