From 27a63cf0742fa75fc51eb6b906a135440a693642 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Sat, 17 Mar 2018 19:02:58 +1100 Subject: tests: Use valgrind client requests for better checking 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 --- 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); -- cgit v1.2.1