Commit d047cd8a authored by Rob Herring's avatar Rob Herring
Browse files

scripts/dtc: Update to upstream version v1.6.0-2-g87a656ae5ff9



This adds the following commits from upstream:

87a656ae5ff9 check: Inform about missing ranges
73d6e9ecb417 libfdt: fix undefined behaviour in fdt_splice_()
2525da3dba9b Bump version to v1.6.0
62cb4ad286ff Execute tests on FreeBSD with Cirrus CI
1f9a41750883 tests: Allow running the testsuite on already installed binary / libraries
c5995ddf4c20 tests: Honour NO_YAML make variable
e4ce227e89d7 tests: Properly clean up .bak file from tests
9b75292c335c tests: Honour $(NO_PYTHON) flag from Makefile in run_tests.sh
6c253afd07d4 Encode $(NO_PYTHON) consistently with other variables
95ec8ef706bd tests: No need to explicitly pass $PYTHON from Make to run_tests.sh
2b5f62d109a2 tests: Let run_tests.sh run Python tests without Makefile assistance
76b43dcbd18a checks: Add 'dma-ranges' check
e5c92a4780c6 libfdt: Use VALID_INPUT for FDT_ERR_BADSTATE checks
e5cc26b68bc0 libfdt: Add support for disabling internal checks
28fd7590aad2 libfdt: Improve comments in some of the assumptions
fc207c32341b libfdt: Fix a few typos
0f61c72dedc4 libfdt: Allow exclusion of fdt_check_full()
f270f45fd5d2 libfdt: Add support for disabling ordering check/fixup
c18bae9a4c96 libfdt: Add support for disabling version checks
fc03c4a2e04e libfdt: Add support for disabling rollback handling
77563ae72b7c libfdt: Add support for disabling sanity checks
57bc6327b80b libfdt: Add support for disabling dtb checks
464962489dcc Add a way to control the level of checks in the code
0c5326cb2845 libfdt: De-inline fdt_header_size()
cc6a5a071504 Revert "yamltree: Ensure consistent bracketing of properties with phandles"
0e9225eb0dfe Remove redundant YYLOC global declaration
cab09eedd644 Move -DNO_VALGRIND into CPPFLAGS
0eb1cb0b531e Makefile: pass $(CFLAGS) also during dependency generation

Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent 78154212
Loading
Loading
Loading
Loading
+14 −11
Original line number Original line Diff line number Diff line
@@ -352,7 +352,7 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
			FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");
			FAIL(c, dti, node, "node has a reg or ranges property, but no unit name");
	} else {
	} else {
		if (unitname[0])
		if (unitname[0])
			FAIL(c, dti, node, "node has a unit name, but no reg property");
			FAIL(c, dti, node, "node has a unit name, but no reg or ranges property");
	}
	}
}
}
WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
@@ -765,13 +765,15 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,
{
{
	struct property *prop;
	struct property *prop;
	int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
	int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
	const char *ranges = c->data;


	prop = get_property(node, "ranges");
	prop = get_property(node, ranges);
	if (!prop)
	if (!prop)
		return;
		return;


	if (!node->parent) {
	if (!node->parent) {
		FAIL_PROP(c, dti, node, prop, "Root node has a \"ranges\" property");
		FAIL_PROP(c, dti, node, prop, "Root node has a \"%s\" property",
			  ranges);
		return;
		return;
	}
	}


@@ -783,23 +785,24 @@ static void check_ranges_format(struct check *c, struct dt_info *dti,


	if (prop->val.len == 0) {
	if (prop->val.len == 0) {
		if (p_addr_cells != c_addr_cells)
		if (p_addr_cells != c_addr_cells)
			FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
			FAIL_PROP(c, dti, node, prop, "empty \"%s\" property but its "
				  "#address-cells (%d) differs from %s (%d)",
				  "#address-cells (%d) differs from %s (%d)",
				  c_addr_cells, node->parent->fullpath,
				  ranges, c_addr_cells, node->parent->fullpath,
				  p_addr_cells);
				  p_addr_cells);
		if (p_size_cells != c_size_cells)
		if (p_size_cells != c_size_cells)
			FAIL_PROP(c, dti, node, prop, "empty \"ranges\" property but its "
			FAIL_PROP(c, dti, node, prop, "empty \"%s\" property but its "
				  "#size-cells (%d) differs from %s (%d)",
				  "#size-cells (%d) differs from %s (%d)",
				  c_size_cells, node->parent->fullpath,
				  ranges, c_size_cells, node->parent->fullpath,
				  p_size_cells);
				  p_size_cells);
	} else if ((prop->val.len % entrylen) != 0) {
	} else if ((prop->val.len % entrylen) != 0) {
		FAIL_PROP(c, dti, node, prop, "\"ranges\" property has invalid length (%d bytes) "
		FAIL_PROP(c, dti, node, prop, "\"%s\" property has invalid length (%d bytes) "
			  "(parent #address-cells == %d, child #address-cells == %d, "
			  "(parent #address-cells == %d, child #address-cells == %d, "
			  "#size-cells == %d)", prop->val.len,
			  "#size-cells == %d)", ranges, prop->val.len,
			  p_addr_cells, c_addr_cells, c_size_cells);
			  p_addr_cells, c_addr_cells, c_size_cells);
	}
	}
}
}
WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
WARNING(ranges_format, check_ranges_format, "ranges", &addr_size_cells);
WARNING(dma_ranges_format, check_ranges_format, "dma-ranges", &addr_size_cells);


static const struct bus_type pci_bus = {
static const struct bus_type pci_bus = {
	.name = "PCI",
	.name = "PCI",
@@ -1780,7 +1783,7 @@ static struct check *check_table[] = {
	&property_name_chars_strict,
	&property_name_chars_strict,
	&node_name_chars_strict,
	&node_name_chars_strict,


	&addr_size_cells, &reg_format, &ranges_format,
	&addr_size_cells, &reg_format, &ranges_format, &dma_ranges_format,


	&unit_address_vs_reg,
	&unit_address_vs_reg,
	&unit_address_format,
	&unit_address_format,
+0 −1
Original line number Original line Diff line number Diff line
@@ -23,7 +23,6 @@ LINECOMMENT "//".*\n
#include "srcpos.h"
#include "srcpos.h"
#include "dtc-parser.tab.h"
#include "dtc-parser.tab.h"


YYLTYPE yylloc;
extern bool treesource_error;
extern bool treesource_error;


/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
+62 −37
Original line number Original line Diff line number Diff line
@@ -19,15 +19,21 @@ int32_t fdt_ro_probe_(const void *fdt)
{
{
	uint32_t totalsize = fdt_totalsize(fdt);
	uint32_t totalsize = fdt_totalsize(fdt);


	if (can_assume(VALID_DTB))
		return totalsize;

	if (fdt_magic(fdt) == FDT_MAGIC) {
	if (fdt_magic(fdt) == FDT_MAGIC) {
		/* Complete tree */
		/* Complete tree */
		if (!can_assume(LATEST)) {
			if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
			if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
				return -FDT_ERR_BADVERSION;
				return -FDT_ERR_BADVERSION;
		if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
			if (fdt_last_comp_version(fdt) >
					FDT_LAST_SUPPORTED_VERSION)
				return -FDT_ERR_BADVERSION;
				return -FDT_ERR_BADVERSION;
		}
	} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
	} else if (fdt_magic(fdt) == FDT_SW_MAGIC) {
		/* Unfinished sequential-write blob */
		/* Unfinished sequential-write blob */
		if (fdt_size_dt_struct(fdt) == 0)
		if (!can_assume(VALID_INPUT) && fdt_size_dt_struct(fdt) == 0)
			return -FDT_ERR_BADSTATE;
			return -FDT_ERR_BADSTATE;
	} else {
	} else {
		return -FDT_ERR_BADMAGIC;
		return -FDT_ERR_BADMAGIC;
@@ -70,29 +76,42 @@ size_t fdt_header_size_(uint32_t version)
		return FDT_V17_SIZE;
		return FDT_V17_SIZE;
}
}


size_t fdt_header_size(const void *fdt)
{
	return can_assume(LATEST) ? FDT_V17_SIZE :
		fdt_header_size_(fdt_version(fdt));
}

int fdt_check_header(const void *fdt)
int fdt_check_header(const void *fdt)
{
{
	size_t hdrsize;
	size_t hdrsize;


	if (fdt_magic(fdt) != FDT_MAGIC)
	if (fdt_magic(fdt) != FDT_MAGIC)
		return -FDT_ERR_BADMAGIC;
		return -FDT_ERR_BADMAGIC;
	hdrsize = fdt_header_size(fdt);
	if (!can_assume(LATEST)) {
		if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
		if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
	    || (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION))
		    || (fdt_last_comp_version(fdt) >
			FDT_LAST_SUPPORTED_VERSION))
			return -FDT_ERR_BADVERSION;
			return -FDT_ERR_BADVERSION;
		if (fdt_version(fdt) < fdt_last_comp_version(fdt))
		if (fdt_version(fdt) < fdt_last_comp_version(fdt))
			return -FDT_ERR_BADVERSION;
			return -FDT_ERR_BADVERSION;
	}
	hdrsize = fdt_header_size(fdt);
	if (!can_assume(VALID_DTB)) {


		if ((fdt_totalsize(fdt) < hdrsize)
		if ((fdt_totalsize(fdt) < hdrsize)
		    || (fdt_totalsize(fdt) > INT_MAX))
		    || (fdt_totalsize(fdt) > INT_MAX))
			return -FDT_ERR_TRUNCATED;
			return -FDT_ERR_TRUNCATED;


		/* Bounds check memrsv block */
		/* Bounds check memrsv block */
	if (!check_off_(hdrsize, fdt_totalsize(fdt), fdt_off_mem_rsvmap(fdt)))
		if (!check_off_(hdrsize, fdt_totalsize(fdt),
				fdt_off_mem_rsvmap(fdt)))
			return -FDT_ERR_TRUNCATED;
			return -FDT_ERR_TRUNCATED;
	}


	if (!can_assume(VALID_DTB)) {
		/* Bounds check structure block */
		/* Bounds check structure block */
	if (fdt_version(fdt) < 17) {
		if (!can_assume(LATEST) && fdt_version(fdt) < 17) {
			if (!check_off_(hdrsize, fdt_totalsize(fdt),
			if (!check_off_(hdrsize, fdt_totalsize(fdt),
					fdt_off_dt_struct(fdt)))
					fdt_off_dt_struct(fdt)))
				return -FDT_ERR_TRUNCATED;
				return -FDT_ERR_TRUNCATED;
@@ -105,8 +124,10 @@ int fdt_check_header(const void *fdt)


		/* Bounds check strings block */
		/* Bounds check strings block */
		if (!check_block_(hdrsize, fdt_totalsize(fdt),
		if (!check_block_(hdrsize, fdt_totalsize(fdt),
			  fdt_off_dt_strings(fdt), fdt_size_dt_strings(fdt)))
				  fdt_off_dt_strings(fdt),
				  fdt_size_dt_strings(fdt)))
			return -FDT_ERR_TRUNCATED;
			return -FDT_ERR_TRUNCATED;
	}


	return 0;
	return 0;
}
}
@@ -115,12 +136,13 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
{
{
	unsigned absoffset = offset + fdt_off_dt_struct(fdt);
	unsigned absoffset = offset + fdt_off_dt_struct(fdt);


	if (!can_assume(VALID_INPUT))
		if ((absoffset < offset)
		if ((absoffset < offset)
		    || ((absoffset + len) < absoffset)
		    || ((absoffset + len) < absoffset)
		    || (absoffset + len) > fdt_totalsize(fdt))
		    || (absoffset + len) > fdt_totalsize(fdt))
			return NULL;
			return NULL;


	if (fdt_version(fdt) >= 0x11)
	if (can_assume(LATEST) || fdt_version(fdt) >= 0x11)
		if (((offset + len) < offset)
		if (((offset + len) < offset)
		    || ((offset + len) > fdt_size_dt_struct(fdt)))
		    || ((offset + len) > fdt_size_dt_struct(fdt)))
			return NULL;
			return NULL;
@@ -137,7 +159,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)


	*nextoffset = -FDT_ERR_TRUNCATED;
	*nextoffset = -FDT_ERR_TRUNCATED;
	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
	tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
	if (!tagp)
	if (!can_assume(VALID_DTB) && !tagp)
		return FDT_END; /* premature end */
		return FDT_END; /* premature end */
	tag = fdt32_to_cpu(*tagp);
	tag = fdt32_to_cpu(*tagp);
	offset += FDT_TAGSIZE;
	offset += FDT_TAGSIZE;
@@ -149,18 +171,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)
		do {
		do {
			p = fdt_offset_ptr(fdt, offset++, 1);
			p = fdt_offset_ptr(fdt, offset++, 1);
		} while (p && (*p != '\0'));
		} while (p && (*p != '\0'));
		if (!p)
		if (!can_assume(VALID_DTB) && !p)
			return FDT_END; /* premature end */
			return FDT_END; /* premature end */
		break;
		break;


	case FDT_PROP:
	case FDT_PROP:
		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
		if (!lenp)
		if (!can_assume(VALID_DTB) && !lenp)
			return FDT_END; /* premature end */
			return FDT_END; /* premature end */
		/* skip-name offset, length and value */
		/* skip-name offset, length and value */
		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
			+ fdt32_to_cpu(*lenp);
			+ fdt32_to_cpu(*lenp);
		if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
		if (!can_assume(LATEST) &&
		    fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
		    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
		    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
			offset += 4;
			offset += 4;
		break;
		break;
@@ -183,6 +206,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)


int fdt_check_node_offset_(const void *fdt, int offset)
int fdt_check_node_offset_(const void *fdt, int offset)
{
{
	if (can_assume(VALID_INPUT))
		return offset;
	if ((offset < 0) || (offset % FDT_TAGSIZE)
	if ((offset < 0) || (offset % FDT_TAGSIZE)
	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
	    || (fdt_next_tag(fdt, offset, &offset) != FDT_BEGIN_NODE))
		return -FDT_ERR_BADOFFSET;
		return -FDT_ERR_BADOFFSET;
+51 −92
Original line number Original line Diff line number Diff line
@@ -33,17 +33,26 @@ static int fdt_nodename_eq_(const void *fdt, int offset,


const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
{
{
	int32_t totalsize = fdt_ro_probe_(fdt);
	int32_t totalsize;
	uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt);
	uint32_t absoffset;
	size_t len;
	size_t len;
	int err;
	int err;
	const char *s, *n;
	const char *s, *n;


	if (can_assume(VALID_INPUT)) {
		s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;

		if (lenp)
			*lenp = strlen(s);
		return s;
	}
	totalsize = fdt_ro_probe_(fdt);
	err = totalsize;
	err = totalsize;
	if (totalsize < 0)
	if (totalsize < 0)
		goto fail;
		goto fail;


	err = -FDT_ERR_BADOFFSET;
	err = -FDT_ERR_BADOFFSET;
	absoffset = stroffset + fdt_off_dt_strings(fdt);
	if (absoffset >= totalsize)
	if (absoffset >= totalsize)
		goto fail;
		goto fail;
	len = totalsize - absoffset;
	len = totalsize - absoffset;
@@ -51,7 +60,7 @@ const char *fdt_get_string(const void *fdt, int stroffset, int *lenp)
	if (fdt_magic(fdt) == FDT_MAGIC) {
	if (fdt_magic(fdt) == FDT_MAGIC) {
		if (stroffset < 0)
		if (stroffset < 0)
			goto fail;
			goto fail;
		if (fdt_version(fdt) >= 17) {
		if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
			if (stroffset >= fdt_size_dt_strings(fdt))
			if (stroffset >= fdt_size_dt_strings(fdt))
				goto fail;
				goto fail;
			if ((fdt_size_dt_strings(fdt) - stroffset) < len)
			if ((fdt_size_dt_strings(fdt) - stroffset) < len)
@@ -151,10 +160,13 @@ static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n)
	int offset = n * sizeof(struct fdt_reserve_entry);
	int offset = n * sizeof(struct fdt_reserve_entry);
	int absoffset = fdt_off_mem_rsvmap(fdt) + offset;
	int absoffset = fdt_off_mem_rsvmap(fdt) + offset;


	if (!can_assume(VALID_INPUT)) {
		if (absoffset < fdt_off_mem_rsvmap(fdt))
		if (absoffset < fdt_off_mem_rsvmap(fdt))
			return NULL;
			return NULL;
	if (absoffset > fdt_totalsize(fdt) - sizeof(struct fdt_reserve_entry))
		if (absoffset > fdt_totalsize(fdt) -
		    sizeof(struct fdt_reserve_entry))
			return NULL;
			return NULL;
	}
	return fdt_mem_rsv_(fdt, n);
	return fdt_mem_rsv_(fdt, n);
}
}


@@ -164,7 +176,7 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)


	FDT_RO_PROBE(fdt);
	FDT_RO_PROBE(fdt);
	re = fdt_mem_rsv(fdt, n);
	re = fdt_mem_rsv(fdt, n);
	if (!re)
	if (!can_assume(VALID_INPUT) && !re)
		return -FDT_ERR_BADOFFSET;
		return -FDT_ERR_BADOFFSET;


	*address = fdt64_ld(&re->address);
	*address = fdt64_ld(&re->address);
@@ -295,7 +307,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)


	nameptr = nh->name;
	nameptr = nh->name;


	if (fdt_version(fdt) < 0x10) {
	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
		/*
		/*
		 * For old FDT versions, match the naming conventions of V16:
		 * For old FDT versions, match the naming conventions of V16:
		 * give only the leaf name (after all /). The actual tree
		 * give only the leaf name (after all /). The actual tree
@@ -346,7 +358,8 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt,
	int err;
	int err;
	const struct fdt_property *prop;
	const struct fdt_property *prop;


	if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) {
	if (!can_assume(VALID_INPUT) &&
	    (err = fdt_check_prop_offset_(fdt, offset)) < 0) {
		if (lenp)
		if (lenp)
			*lenp = err;
			*lenp = err;
		return NULL;
		return NULL;
@@ -367,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt,
	/* Prior to version 16, properties may need realignment
	/* Prior to version 16, properties may need realignment
	 * and this API does not work. fdt_getprop_*() will, however. */
	 * and this API does not work. fdt_getprop_*() will, however. */


	if (fdt_version(fdt) < 0x10) {
	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
		if (lenp)
		if (lenp)
			*lenp = -FDT_ERR_BADVERSION;
			*lenp = -FDT_ERR_BADVERSION;
		return NULL;
		return NULL;
@@ -388,7 +401,8 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt,
	     (offset = fdt_next_property_offset(fdt, offset))) {
	     (offset = fdt_next_property_offset(fdt, offset))) {
		const struct fdt_property *prop;
		const struct fdt_property *prop;


		if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) {
		prop = fdt_get_property_by_offset_(fdt, offset, lenp);
		if (!can_assume(LIBFDT_FLAWLESS) && !prop) {
			offset = -FDT_ERR_INTERNAL;
			offset = -FDT_ERR_INTERNAL;
			break;
			break;
		}
		}
@@ -413,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt,
{
{
	/* Prior to version 16, properties may need realignment
	/* Prior to version 16, properties may need realignment
	 * and this API does not work. fdt_getprop_*() will, however. */
	 * and this API does not work. fdt_getprop_*() will, however. */
	if (fdt_version(fdt) < 0x10) {
	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10) {
		if (lenp)
		if (lenp)
			*lenp = -FDT_ERR_BADVERSION;
			*lenp = -FDT_ERR_BADVERSION;
		return NULL;
		return NULL;
@@ -444,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
		return NULL;
		return NULL;


	/* Handle realignment */
	/* Handle realignment */
	if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 &&
	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
	    fdt32_ld(&prop->len) >= 8)
	    (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
		return prop->data + 4;
		return prop->data + 4;
	return prop->data;
	return prop->data;
}
}
@@ -461,6 +475,8 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
	if (namep) {
	if (namep) {
		const char *name;
		const char *name;
		int namelen;
		int namelen;

		if (!can_assume(VALID_INPUT)) {
			name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
			name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff),
					      &namelen);
					      &namelen);
			if (!name) {
			if (!name) {
@@ -469,11 +485,14 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset,
				return NULL;
				return NULL;
			}
			}
			*namep = name;
			*namep = name;
		} else {
			*namep = fdt_string(fdt, fdt32_ld(&prop->nameoff));
		}
	}
	}


	/* Handle realignment */
	/* Handle realignment */
	if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 &&
	if (!can_assume(LATEST) && fdt_version(fdt) < 0x10 &&
	    fdt32_ld(&prop->len) >= 8)
	    (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8)
		return prop->data + 4;
		return prop->data + 4;
	return prop->data;
	return prop->data;
}
}
@@ -598,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
		}
		}
	}
	}


	if (!can_assume(VALID_INPUT)) {
		if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
		if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))
			return -FDT_ERR_BADOFFSET;
			return -FDT_ERR_BADOFFSET;
		else if (offset == -FDT_ERR_BADOFFSET)
		else if (offset == -FDT_ERR_BADOFFSET)
			return -FDT_ERR_BADSTRUCTURE;
			return -FDT_ERR_BADSTRUCTURE;
	}


	return offset; /* error from fdt_next_node() */
	return offset; /* error from fdt_next_node() */
}
}
@@ -613,7 +634,8 @@ int fdt_node_depth(const void *fdt, int nodeoffset)


	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
	if (err)
	if (err)
		return (err < 0) ? err : -FDT_ERR_INTERNAL;
		return (can_assume(LIBFDT_FLAWLESS) || err < 0) ? err :
			-FDT_ERR_INTERNAL;
	return nodedepth;
	return nodedepth;
}
}


@@ -833,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;
		}
	}
}
+29 −13
Original line number Original line Diff line number Diff line
@@ -24,14 +24,16 @@ static int fdt_blocks_misordered_(const void *fdt,


static int fdt_rw_probe_(void *fdt)
static int fdt_rw_probe_(void *fdt)
{
{
	if (can_assume(VALID_DTB))
		return 0;
	FDT_RO_PROBE(fdt);
	FDT_RO_PROBE(fdt);


	if (fdt_version(fdt) < 17)
	if (!can_assume(LATEST) && fdt_version(fdt) < 17)
		return -FDT_ERR_BADVERSION;
		return -FDT_ERR_BADVERSION;
	if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
	if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry),
				   fdt_size_dt_struct(fdt)))
				   fdt_size_dt_struct(fdt)))
		return -FDT_ERR_BADLAYOUT;
		return -FDT_ERR_BADLAYOUT;
	if (fdt_version(fdt) > 17)
	if (!can_assume(LATEST) && fdt_version(fdt) > 17)
		fdt_set_version(fdt, 17);
		fdt_set_version(fdt, 17);


	return 0;
	return 0;
@@ -44,7 +46,7 @@ static int fdt_rw_probe_(void *fdt)
			return err_; \
			return err_; \
	}
	}


static inline int fdt_data_size_(void *fdt)
static inline unsigned int fdt_data_size_(void *fdt)
{
{
	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
	return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
}
}
@@ -52,15 +54,16 @@ static inline int fdt_data_size_(void *fdt)
static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
static int fdt_splice_(void *fdt, void *splicepoint, int oldlen, int newlen)
{
{
	char *p = splicepoint;
	char *p = splicepoint;
	char *end = (char *)fdt + fdt_data_size_(fdt);
	unsigned int dsize = fdt_data_size_(fdt);
	size_t soff = p - (char *)fdt;


	if (((p + oldlen) < p) || ((p + oldlen) > end))
	if ((oldlen < 0) || (soff + oldlen < soff) || (soff + oldlen > dsize))
		return -FDT_ERR_BADOFFSET;
		return -FDT_ERR_BADOFFSET;
	if ((p < (char *)fdt) || ((end - oldlen + newlen) < (char *)fdt))
	if ((p < (char *)fdt) || (dsize + newlen < oldlen))
		return -FDT_ERR_BADOFFSET;
		return -FDT_ERR_BADOFFSET;
	if ((end - oldlen + newlen) > ((char *)fdt + fdt_totalsize(fdt)))
	if (dsize - oldlen + newlen > fdt_totalsize(fdt))
		return -FDT_ERR_NOSPACE;
		return -FDT_ERR_NOSPACE;
	memmove(p + newlen, p + oldlen, end - p - oldlen);
	memmove(p + newlen, p + oldlen, ((char *)fdt + dsize) - (p + oldlen));
	return 0;
	return 0;
}
}


@@ -112,6 +115,15 @@ static int fdt_splice_string_(void *fdt, int newlen)
	return 0;
	return 0;
}
}


/**
 * fdt_find_add_string_() - Find or allocate a string
 *
 * @fdt: pointer to the device tree to check/adjust
 * @s: string to find/add
 * @allocated: Set to 0 if the string was found, 1 if not found and so
 *	allocated. Ignored if can_assume(NO_ROLLBACK)
 * @return offset of string in the string table (whether found or added)
 */
static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
{
{
	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
	char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
@@ -120,6 +132,7 @@ static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
	int len = strlen(s) + 1;
	int len = strlen(s) + 1;
	int err;
	int err;


	if (!can_assume(NO_ROLLBACK))
		*allocated = 0;
		*allocated = 0;


	p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
	p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s);
@@ -132,6 +145,7 @@ static int fdt_find_add_string_(void *fdt, const char *s, int *allocated)
	if (err)
	if (err)
		return err;
		return err;


	if (!can_assume(NO_ROLLBACK))
		*allocated = 1;
		*allocated = 1;


	memcpy(new, s, len);
	memcpy(new, s, len);
@@ -206,7 +220,8 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name,


	err = fdt_splice_struct_(fdt, *prop, 0, proplen);
	err = fdt_splice_struct_(fdt, *prop, 0, proplen);
	if (err) {
	if (err) {
		if (allocated)
		/* Delete the string if we failed to add it */
		if (!can_assume(NO_ROLLBACK) && allocated)
			fdt_del_last_string_(fdt, name);
			fdt_del_last_string_(fdt, name);
		return err;
		return err;
	}
	}
@@ -411,7 +426,7 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
		* sizeof(struct fdt_reserve_entry);
		* sizeof(struct fdt_reserve_entry);


	if (fdt_version(fdt) >= 17) {
	if (can_assume(LATEST) || fdt_version(fdt) >= 17) {
		struct_size = fdt_size_dt_struct(fdt);
		struct_size = fdt_size_dt_struct(fdt);
	} else {
	} else {
		struct_size = 0;
		struct_size = 0;
@@ -421,7 +436,8 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
			return struct_size;
			return struct_size;
	}
	}


	if (!fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
	if (can_assume(LIBFDT_ORDER) |
	    !fdt_blocks_misordered_(fdt, mem_rsv_size, struct_size)) {
		/* no further work necessary */
		/* no further work necessary */
		err = fdt_move(fdt, buf, bufsize);
		err = fdt_move(fdt, buf, bufsize);
		if (err)
		if (err)
Loading