aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2017-10-23 06:45:56 +0300
committerDavid Gibson <david@gibson.dropbear.id.au>2018-06-07 11:47:59 +1000
commiteb890c0f77dcd98bb3f24755d50dfbe5eba11340 (patch)
tree7ba41d27e196479c218b2aa61c81608083993661 /tests
parent899d6fad93f328872477f28e0d69989a33607be7 (diff)
downloaddtc-eb890c0f77dcd98bb3f24755d50dfbe5eba11340.zip
dtc-eb890c0f77dcd98bb3f24755d50dfbe5eba11340.tar.gz
dtc-eb890c0f77dcd98bb3f24755d50dfbe5eba11340.tar.bz2
libfdt: Make fdt_check_header() more thorough
Currently fdt_check_header() performs only some rudimentary checks, which is not really what the name suggests. This strengthens fdt_check_header() to check as much about the blob as is possible from the header alone: as well as checking the magic number and version, it checks that the total size is sane, and that all the sub-blocks within the blob lie within the total size. * This broadens the meaning of FDT_ERR_TRUNCATED to cover all sorts of improperly terminated blocks as well as just a structure block without FDT_END. * This makes fdt_check_header() only succeed on "complete" blobs, not in-progress sequential write blobs. The only reason this didn't fail before was that this function used to be called by many RO functions which are supposed to also work on incomplete SW blobs. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.tests2
-rw-r--r--tests/check_header.c128
-rwxr-xr-xtests/run_tests.sh2
4 files changed, 132 insertions, 1 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index c79496f..62be2ec 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -8,6 +8,7 @@ tmp.*
/asm_tree_dump
/boot-cpuid
/char_literal
+/check_header
/check_path
/del_node
/del_property
diff --git a/tests/Makefile.tests b/tests/Makefile.tests
index ed7efbc..c670100 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_path check_header
LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%)
LIBTREE_TESTS_L = truncated_property
diff --git a/tests/check_header.c b/tests/check_header.c
new file mode 100644
index 0000000..5e37813
--- /dev/null
+++ b/tests/check_header.c
@@ -0,0 +1,128 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Testcase for fdt_check_header
+ * Copyright (C) 2018 David Gibson
+ *
+ * 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 <stdio.h>
+
+#include <libfdt.h>
+
+#include "tests.h"
+
+static void *dtdup(void *dt)
+{
+ size_t bufsize = fdt_totalsize(dt);
+ void *buf = xmalloc(bufsize);
+ fdt_move(dt, buf, bufsize);
+ return buf;
+}
+
+#define CHECK_MANGLE(exerr, code) \
+ do { \
+ void *fdt = dtdup(template); \
+ { code } \
+ err = fdt_check_header(fdt); \
+ verbose_printf("\"%s\" => %s\n", #code, fdt_strerror(err)); \
+ if (err != (exerr)) \
+ FAIL("fdt_check_header() didn't catch mangle %s", \
+ #code); \
+ free(fdt); \
+ } while (0)
+
+int main(int argc, char *argv[])
+{
+ void *template;
+ int err;
+
+ test_init(argc, argv);
+ template = load_blob(argv[1]);
+
+ /* Check that the base dt is valid before mangling it */
+ err = fdt_check_header(template);
+ if (err != 0)
+ FAIL("Base tree fails: %s", fdt_strerror(err));
+
+ /* Check a no-op mangle doesn't break things */
+ CHECK_MANGLE(0, ; );
+
+ /* Mess up the magic number */
+ CHECK_MANGLE(-FDT_ERR_BADMAGIC,
+ fdt_set_magic(fdt, fdt_magic(fdt) ^ 0x1);
+ );
+ CHECK_MANGLE(-FDT_ERR_BADMAGIC,
+ fdt_set_magic(fdt, fdt_magic(fdt) ^ 0x80000000);
+ );
+
+ /* Mess up the version */
+ CHECK_MANGLE(-FDT_ERR_BADVERSION,
+ fdt_set_version(fdt, FDT_FIRST_SUPPORTED_VERSION - 1);
+ fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION - 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_BADVERSION,
+ fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION + 1);
+ fdt_set_last_comp_version(fdt, FDT_LAST_SUPPORTED_VERSION + 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_BADVERSION,
+ fdt_set_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
+ fdt_set_last_comp_version(fdt, FDT_LAST_SUPPORTED_VERSION);
+ );
+
+ /* Out of bounds sizes */
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, FDT_V1_SIZE - 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, (uint32_t)INT_MAX + 1);
+ );
+
+ /* Truncate within various blocks */
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, fdt_off_dt_struct(fdt) - 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, fdt_off_dt_strings(fdt) - 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, fdt_off_mem_rsvmap(fdt) - 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, fdt_off_dt_struct(fdt) + 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, fdt_off_dt_strings(fdt) + 1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_totalsize(fdt, fdt_off_mem_rsvmap(fdt) + 1);
+ );
+
+ /* Negative block sizes */
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_size_dt_struct(fdt, (uint32_t)-1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_size_dt_strings(fdt, (uint32_t)-1);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_size_dt_struct(fdt, (uint32_t)INT_MIN);
+ );
+ CHECK_MANGLE(-FDT_ERR_TRUNCATED,
+ fdt_set_size_dt_strings(fdt, (uint32_t)INT_MIN);
+ );
+
+ PASS();
+}
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 61ec80b..dc7f1ef 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -441,6 +441,8 @@ libfdt_tests () {
run_wrap_error_test $DTC nul-in-line-info2.dts
run_wrap_error_test $DTC -I dtb -O dts -o /dev/null ovf_size_strings.dtb
+
+ run_test check_header test_tree1.dtb
}
dtc_tests () {