summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gibson <dgibson@sneetch.(none)>2006-12-14 15:29:25 +1100
committerDavid Gibson <dgibson@sneetch.(none)>2006-12-14 15:29:25 +1100
commit9825f823eb5c9fc6b01e40f1b84108f5574235f2 (patch)
treec01ac4522a04d36df2d92145667228454c705f9c
parent6ae4de5c81eac62a0c658ef302c850da3f107092 (diff)
downloaddevice-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.c2
-rw-r--r--tests/Makefile5
-rwxr-xr-xtests/run_tests.sh3
-rw-r--r--tests/testdata.h1
-rw-r--r--tests/trees.S14
-rw-r--r--tests/truncated_property.c49
6 files changed, 72 insertions, 2 deletions
diff --git a/fdt_ro.c b/fdt_ro.c
index bd58227..1b2383c 100644
--- a/fdt_ro.c
+++ b/fdt_ro.c
@@ -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();
+}