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

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



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.





> +	else if (!expect_bad && (err != 0))
> +		FAIL("fdt_check_full() failed: %s", fdt_strerror(err));
> +
> +	PASS();
> +}
> diff --git a/tests/dumptrees.c b/tests/dumptrees.c
> index 87d1c3d..ff5818d 100644
> --- a/tests/dumptrees.c
> +++ b/tests/dumptrees.c
> @@ -37,6 +37,8 @@ static struct {
>  	TREE(test_tree1),
>  	TREE(bad_node_char), TREE(bad_node_format), TREE(bad_prop_char),
>  	TREE(ovf_size_strings),
> +	TREE(truncated_property), TREE(truncated_string),
> +	TREE(truncated_memrsv),
>  };
>  
>  #define NUM_TREES	(sizeof(trees) / sizeof(trees[0]))
> diff --git a/tests/run_tests.sh b/tests/run_tests.sh
> index ee5a43a..615b86d 100755
> --- a/tests/run_tests.sh
> +++ b/tests/run_tests.sh
> @@ -445,6 +445,15 @@ libfdt_tests () {
>  
>      # Check header tests
>      run_test check_header test_tree1.dtb
> +
> +    # check full tests
> +    for good in test_tree1.dtb; do
> +	run_test check_full $good
> +    done
> +    for bad in truncated_property.dtb truncated_string.dtb \
> +				      truncated_memrsv.dtb; do
> +	run_test check_full -n $bad
> +    done
>  }
>  
>  dtc_tests () {
> 


-- 
Alexey
--
To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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