Re: [PATCH 12/12] libfdt: Add fdt_check_full() function

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



On Tue, Mar 27, 2018 at 05:10:43PM +1100, Alexey Kardashevskiy wrote:
> On 26/3/18 10:25 am, David Gibson wrote:
> > This new function implements a complete and thorough check of an fdt blob's
> > structure.  Given a buffer containing an fdt, it should return 0 only if
> > the fdt within is structurally sound in all regards.  It doesn't check
> > anything about the blob's contents (i.e. the actual values of the nodes and
> > properties), of course.
> > 
> > Signed-off-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>
> > ---
> >  libfdt/fdt_ro.c      | 57 +++++++++++++++++++++++++++++++++++++++++++++++
> >  libfdt/libfdt.h      |  2 ++
> >  tests/.gitignore     |  1 +
> >  tests/Makefile.tests |  2 +-
> >  tests/check_full.c   | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  tests/dumptrees.c    |  2 ++
> >  tests/run_tests.sh   |  9 ++++++++
> >  7 files changed, 135 insertions(+), 1 deletion(-)
> >  create mode 100644 tests/check_full.c
> > 
> > diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
> > index c74b962..4dbd0c5 100644
> > --- a/libfdt/fdt_ro.c
> > +++ b/libfdt/fdt_ro.c
> > @@ -857,3 +857,60 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
> >  
> >  	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;
> > +
> > +	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:
> > +			break;
> > +
> > +		default:
> > +			return -FDT_ERR_INTERNAL;
> > +		}
> > +	}
> > +}
> > diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
> > index 9938fb8..f044298 100644
> > --- a/libfdt/libfdt.h
> > +++ b/libfdt/libfdt.h
> > @@ -295,6 +295,8 @@ int fdt_move(const void *fdt, void *buf, int bufsize);
> >  /* Read-only functions                                                */
> >  /**********************************************************************/
> >  
> > +int fdt_check_full(const void *fdt, size_t bufsize);
> > +
> >  /**
> >   * fdt_get_string - retrieve a string from the strings block of a device tree
> >   * @fdt: pointer to the device tree blob
> > diff --git a/tests/.gitignore b/tests/.gitignore
> > index 60bbb09..9fce43a 100644
> > --- a/tests/.gitignore
> > +++ b/tests/.gitignore
> > @@ -8,6 +8,7 @@ tmp.*
> >  /asm_tree_dump
> >  /boot-cpuid
> >  /char_literal
> > +/check_full
> >  /check_header
> >  /check_path
> >  /del_node
> > diff --git a/tests/Makefile.tests b/tests/Makefile.tests
> > index fc1b160..b73a19a 100644
> > --- a/tests/Makefile.tests
> > +++ b/tests/Makefile.tests
> > @@ -26,7 +26,7 @@ LIB_TESTS_L = get_mem_rsv \
> >  	property_iterate \
> >  	subnode_iterate \
> >  	overlay overlay_bad_fixup \
> > -	check_path check_header
> > +	check_path check_header check_full
> >  LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)
> >  
> >  LIBTREE_TESTS_L = truncated_property truncated_string truncated_memrsv
> > diff --git a/tests/check_full.c b/tests/check_full.c
> > new file mode 100644
> > index 0000000..04c0bc1
> > --- /dev/null
> > +++ b/tests/check_full.c
> > @@ -0,0 +1,63 @@
> > +/*
> > + * libfdt - Flat Device Tree manipulation
> > + *	Tests if two given dtbs are structurally equal (including order)
> > + * Copyright (C) 2007 David Gibson, IBM Corporation.
> > + *
> > + * This library is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public License
> > + * as published by the Free Software Foundation; either version 2.1 of
> > + * the License, or (at your option) any later version.
> > + *
> > + * This library is distributed in the hope that it will be useful, but
> > + * WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with this library; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
> > + */
> > +
> > +#include <stdlib.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <stdint.h>
> > +
> > +#include <libfdt.h>
> > +
> > +#include "tests.h"
> > +#include "testdata.h"
> > +
> > +static int expect_bad; /* = 0 */
> > +
> > +int main(int argc, char *argv[])
> > +{
> > +	const char *filename;
> > +	char *fdt;
> > +	size_t len;
> > +	int err;
> > +
> > +	test_init(argc, argv);
> > +	if ((argc != 2)
> > +	    && ((argc != 3) || !streq(argv[1], "-n")))
> > +		CONFIG("Usage: %s [-n] <dtb file>", argv[0]);
> > +	if (argc == 3)
> > +		expect_bad = 1;
> > +
> > +	filename = argv[argc-1];
> > +	err = utilfdt_read_err(filename, &fdt, &len);
> > +	if (err)
> > +		CONFIG("Couldn't open blob from \"%s\": %s",
> > +		       filename, strerror(err));
> > +
> > +	vg_prepare_blob(fdt, len);
> > +
> > +	err = fdt_check_full(fdt, len);
> > +
> > +	if (expect_bad && (err == 0))
> > +		FAIL("fdt_check_full() succeeded unexpectedly");
> 
> 
> 
> check_full -n truncated_string.dtb:	FAIL	fdt_check_full() succeeded
> unexpectedly
> 
> Fails on both ppc64be and x86.

Dammit.  The code to actually verify properties is missing.  I swear I
implemented that, but I must have lost it with a careless rebase ore
something.

Fixed up again now.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux