[PATCH 11/12] tests: Use valgrind client requests for better checking

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



libfdt is never supposed to access memory outside the the blob, or outside
the sub-blocks within it, even if the blob is badly corrupted.

We can leverage valgrind's client requests to do better testing of this.
This adds a vg_prepare_blob() function which marks just the valid parts of
an fdt blob as properly initialized, explicitly marking the rest as
uninitialized.  This means valgrind should catch any bad accesses.

We add a call to vg_prepare_blob() to load_blob() so that lots of the
existing testcases will benefit from the extra checking.

Signed-off-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>
---
 tests/tests.h              |  1 +
 tests/testutils.c          | 52 +++++++++++++++++++++++++++++++++++++++++++++-
 tests/truncated_property.c |  2 ++
 tests/truncated_string.c   |  2 ++
 4 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/tests/tests.h b/tests/tests.h
index df38b77..b7daa26 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -119,6 +119,7 @@ const void *check_getprop(void *fdt, int nodeoffset, const char *name,
 #define check_getprop_string(fdt, nodeoffset, name, s) \
 	check_getprop((fdt), (nodeoffset), (name), strlen(s)+1, (s))
 int nodename_eq(const char *s1, const char *s2);
+void vg_prepare_blob(void *fdt, size_t bufsize);
 void *load_blob(const char *filename);
 void *load_blob_arg(int argc, char *argv[]);
 void save_blob(const char *filename, void *blob);
diff --git a/tests/testutils.c b/tests/testutils.c
index d6d6818..ea8a022 100644
--- a/tests/testutils.c
+++ b/tests/testutils.c
@@ -161,14 +161,64 @@ int nodename_eq(const char *s1, const char *s2)
 		return 0;
 }
 
+void vg_prepare_blob(void *fdt, size_t bufsize)
+{
+	char *blob = fdt;
+	int off_memrsv, off_strings, off_struct;
+	size_t size_memrsv, size_strings, size_struct;
+
+	size_memrsv = (fdt_num_mem_rsv(fdt) + 1)
+		* sizeof(struct fdt_reserve_entry);
+
+	VALGRIND_MAKE_MEM_UNDEFINED(blob, bufsize);
+	VALGRIND_MAKE_MEM_DEFINED(blob, FDT_V1_SIZE);
+	VALGRIND_MAKE_MEM_DEFINED(blob, fdt_header_size(fdt));
+
+	if (fdt_magic(fdt) == FDT_MAGIC) {
+		off_memrsv = fdt_off_mem_rsvmap(fdt);
+
+		off_strings = fdt_off_dt_strings(fdt);
+		if (fdt_version(fdt) >= 3)
+			size_strings = fdt_size_dt_strings(fdt);
+		else
+			size_strings = fdt_totalsize(fdt) - off_strings;
+
+		off_struct = fdt_off_dt_struct(fdt);
+		if (fdt_version(fdt) >= 17)
+			size_struct = fdt_size_dt_struct(fdt);
+		else
+			size_struct = fdt_totalsize(fdt) - off_struct;
+	} else if (fdt_magic(fdt) == (~FDT_MAGIC)) {
+		off_memrsv = fdt_off_mem_rsvmap(fdt);
+
+		size_strings = fdt_size_dt_strings(fdt);
+		off_strings = fdt_off_dt_strings(fdt) - size_strings;
+
+		off_struct = fdt_off_dt_struct(fdt);
+		size_struct = fdt_size_dt_struct(fdt);
+		size_struct = fdt_totalsize(fdt) - off_struct;
+
+	} else {
+		CONFIG("Bad magic on vg_prepare_blob()");
+	}
+
+	VALGRIND_MAKE_MEM_DEFINED(blob + off_memrsv, size_memrsv);
+	VALGRIND_MAKE_MEM_DEFINED(blob + off_strings, size_strings);
+	VALGRIND_MAKE_MEM_DEFINED(blob + off_struct, size_struct);
+}
+
 void *load_blob(const char *filename)
 {
 	char *blob;
-	int ret = utilfdt_read_err(filename, &blob, NULL);
+	size_t len;
+	int ret = utilfdt_read_err(filename, &blob, &len);
 
 	if (ret)
 		CONFIG("Couldn't open blob from \"%s\": %s", filename,
 		       strerror(ret));
+
+	vg_prepare_blob(blob, len);
+
 	return blob;
 }
 
diff --git a/tests/truncated_property.c b/tests/truncated_property.c
index 71619bb..f4b6770 100644
--- a/tests/truncated_property.c
+++ b/tests/truncated_property.c
@@ -36,6 +36,8 @@ int main(int argc, char *argv[])
 
 	test_init(argc, argv);
 
+	vg_prepare_blob(fdt, fdt_totalsize(fdt));
+
 	prop = fdt_getprop(fdt, 0, "truncated", &len);
 	if (prop)
 		FAIL("fdt_getprop() succeeded on truncated property");
diff --git a/tests/truncated_string.c b/tests/truncated_string.c
index 63214d2..5365f69 100644
--- a/tests/truncated_string.c
+++ b/tests/truncated_string.c
@@ -37,6 +37,8 @@ int main(int argc, char *argv[])
 
 	test_init(argc, argv);
 
+	vg_prepare_blob(fdt, fdt_totalsize(fdt));
+
 	off = fdt_first_property_offset(fdt, 0);
 	good = fdt_get_property_by_offset(fdt, off, NULL);
 
-- 
2.14.3

--
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