diff options
author | David Gibson <dgibson@sneetch.(none)> | 2006-12-14 15:29:25 +1100 |
---|---|---|
committer | David Gibson <dgibson@sneetch.(none)> | 2006-12-14 15:29:25 +1100 |
commit | 9825f823eb5c9fc6b01e40f1b84108f5574235f2 (patch) | |
tree | c01ac4522a04d36df2d92145667228454c705f9c | |
parent | 6ae4de5c81eac62a0c658ef302c850da3f107092 (diff) | |
download | device-tree-compiler-9825f823eb5c9fc6b01e40f1b84108f5574235f2.tar.gz |
libfdt: Fix bounds-checking bug in fdt_get_property()
The libfdt functions are supposed to behave tolerably well when practical,
even if given a corrupted device tree as input. A silly mistake in
fdt_get_property() means we're bounds checking against the size of a pointer
instead of the size of a property header, meaning we can get bogus
behaviour in a corrupted device tree where the structure block ends in
what's supposed to be the middle of a property.
This patch corrects the problem (fdt_get_property() will now return
BADSTRUCTURE in this case), and also adds a testcase to catch the bug.
-rw-r--r-- | fdt_ro.c | 2 | ||||
-rw-r--r-- | tests/Makefile | 5 | ||||
-rwxr-xr-x | tests/run_tests.sh | 3 | ||||
-rw-r--r-- | tests/testdata.h | 1 | ||||
-rw-r--r-- | tests/trees.S | 14 | ||||
-rw-r--r-- | tests/truncated_property.c | 49 |
6 files changed, 72 insertions, 2 deletions
@@ -193,7 +193,7 @@ struct fdt_property *fdt_get_property(const struct fdt_header *fdt, /* Found it! */ int len = fdt32_to_cpu(prop->len); prop = fdt_offset_ptr(fdt, offset, - sizeof(prop)+len); + sizeof(*prop)+len); if (! prop) return PTR_ERROR(FDT_ERR_BADSTRUCTURE); diff --git a/tests/Makefile b/tests/Makefile index b0c4571..533c98e 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -6,7 +6,8 @@ LIB_TESTS = root_node find_property subnode_offset path_offset getprop \ sw_tree1 \ move_and_save \ open_pack rw_tree1 setprop del_property del_node -TESTS = $(LIB_TESTS) +LIBTREE_TESTS = truncated_property +TESTS = $(LIB_TESTS) $(LIBTREE_TESTS) UTILS = dumptrees TREES = test_tree1.dtb @@ -42,6 +43,8 @@ all: $(TESTS) $(TREES) $(LIB_TESTS): %: testutils.o $(LIBFDT) +$(LIBTREE_TESTS): %: testutils.o trees.o $(LIBFDT) + dumptrees: %: trees.o $(TREES): dumptrees diff --git a/tests/run_tests.sh b/tests/run_tests.sh index c9c9879..f4a5a54 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -58,6 +58,9 @@ functional_tests () { run_test del_node test_tree1.dtb run_test rw_tree1 tree1_tests rw_tree1.test.dtb + + # Tests for behaviour on various sorts of corrupted trees + run_test truncated_property } stress_tests () { diff --git a/tests/testdata.h b/tests/testdata.h index 318b95f..822c69a 100644 --- a/tests/testdata.h +++ b/tests/testdata.h @@ -5,4 +5,5 @@ #ifndef __ASSEMBLY__ extern struct fdt_header _test_tree1; +extern struct fdt_header _truncated_property; #endif /* ! __ASSEMBLY */ diff --git a/tests/trees.S b/tests/trees.S index ca8e145..397c151 100644 --- a/tests/trees.S +++ b/tests/trees.S @@ -18,6 +18,7 @@ .byte (val) & 0xff #define TREE_HDR(tree) \ + .balign 4 ; \ .globl _##tree ; \ _##tree: \ tree: \ @@ -100,3 +101,16 @@ test_tree1_strings: STRING(test_tree1, prop_int, "prop-int") STRING(test_tree1, prop_str, "prop-str") test_tree1_end: + + TREE_HDR(truncated_property) +truncated_property_rsvmap: + RSVMAP_ENTRY(0, 0) + +truncated_property_struct: + BEGIN_NODE("") + PROPHDR(truncated_property, prop_truncated, 4) + /* Oops, no actual property data here */ + +truncated_property_strings: + STRING(truncated_property, prop_truncated, "truncated") +truncated_property_end: diff --git a/tests/truncated_property.c b/tests/truncated_property.c new file mode 100644 index 0000000..e678b96 --- /dev/null +++ b/tests/truncated_property.c @@ -0,0 +1,49 @@ +/* + * libfdt - Flat Device Tree manipulation + * Testcase for misbehaviour on a truncated property + * Copyright (C) 2006 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 <fdt.h> +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +int main(int argc, char *argv[]) +{ + void *fdt = &_truncated_property; + void *prop; + int err; + int len; + + test_init(argc, argv); + + prop = fdt_getprop(fdt, 0, "truncated", &len); + err = fdt_ptr_error(prop); + if (! err) + FAIL("fdt_getprop() succeeded on truncated property"); + if (err != FDT_ERR_BADSTRUCTURE) + FAIL("fdt_getprop() failed with \"%s\" instead of \"%s\"", + fdt_strerror(err), fdt_strerror(FDT_ERR_BADSTRUCTURE)); + + PASS(); +} |