diff options
author | Pierre-Clément Tosi <ptosi@google.com> | 2023-10-12 22:28:58 +0100 |
---|---|---|
committer | Pierre-Clément Tosi <ptosi@google.com> | 2023-10-12 22:33:06 +0100 |
commit | c566e548af7dd8df8f17ce1d3fc3b8317de8b249 (patch) | |
tree | a754c6f4a1babf890fe0800616ee08d9d45f7439 | |
parent | 0e7797a53c131f9174d4f3a41cab04b477def75a (diff) | |
download | dtc-c566e548af7dd8df8f17ce1d3fc3b8317de8b249.tar.gz |
ANDROID: fuzzing: Sync main-trusty with main
Some commits were merge into main from internal and somehow weren't
picked up by the automerger from main to main-trusty so replicate the
contents of fuzzing/ on that branch (the only diff with main) to avoid
future automerger conflicts. This imports changes from
cca1ca7 Improve fuzzer coverage.
404f524 Improve fuzzer coverage with some additional corpus entires.
c222e9b Removed cc_afl_fuzz build target. cc_afl_fuzz is being removed and AFL fuzzers will now be built through a command line arg FUZZ_FRAMEWORK=AFL Test: built locally
70fd2e8 ANDROID: fuzz: Check for NULL property during walk
3745ef3 Revert "Revert "Enhance fuzzer coverage.""
6fc375c Revert "Enhance fuzzer coverage."
5b4d456 Fix null-pointer dereference on malformed dtb parsing in fdt_check_full(). Add example of malformed input to fuzz corpus.
c409d7c Enhance fuzzer coverage. Add AFL-based fuzzer. Add corpus with one valid and one invalid dtb file.
bd0e292 Change cpp to c file ahead of further extensions to the fuzzing test harness. This simplifies building afl-fuzz or with just C tools, but could be made C++ again if needed in the future.
Test: N/A
Change-Id: Iec28ab9c8e45dc4891e7fac98ae23c01377cccc7
-rw-r--r-- | fuzzing/Android.bp | 1 | ||||
-rw-r--r-- | fuzzing/corpus/crash-a5b94d95681291f3057eea7f0233c8f1529b2f59 | bin | 0 -> 1369 bytes | |||
-rw-r--r-- | fuzzing/corpus/hardy-octopus | bin | 0 -> 1171 bytes | |||
-rw-r--r-- | fuzzing/corpus/header-truncated | bin | 0 -> 40 bytes | |||
-rw-r--r-- | fuzzing/corpus/header-v-1 | bin | 0 -> 40 bytes | |||
-rw-r--r-- | fuzzing/corpus/header-v0 | bin | 0 -> 40 bytes | |||
-rw-r--r-- | fuzzing/corpus/meson-g12a-sei510-android.dtb | bin | 0 -> 1363 bytes | |||
-rw-r--r-- | fuzzing/corpus/oob_by_one | bin | 0 -> 256 bytes | |||
-rw-r--r-- | fuzzing/corpus/quirks.dtb | bin | 0 -> 327 bytes | |||
-rw-r--r-- | fuzzing/libfdt_fuzzer.c | 78 |
10 files changed, 78 insertions, 1 deletions
diff --git a/fuzzing/Android.bp b/fuzzing/Android.bp index 5c22cb4..857c611 100644 --- a/fuzzing/Android.bp +++ b/fuzzing/Android.bp @@ -19,3 +19,4 @@ cc_fuzz { }, host_supported: true, } + diff --git a/fuzzing/corpus/crash-a5b94d95681291f3057eea7f0233c8f1529b2f59 b/fuzzing/corpus/crash-a5b94d95681291f3057eea7f0233c8f1529b2f59 Binary files differnew file mode 100644 index 0000000..dbab42e --- /dev/null +++ b/fuzzing/corpus/crash-a5b94d95681291f3057eea7f0233c8f1529b2f59 diff --git a/fuzzing/corpus/hardy-octopus b/fuzzing/corpus/hardy-octopus Binary files differnew file mode 100644 index 0000000..81615e9 --- /dev/null +++ b/fuzzing/corpus/hardy-octopus diff --git a/fuzzing/corpus/header-truncated b/fuzzing/corpus/header-truncated Binary files differnew file mode 100644 index 0000000..1db29d8 --- /dev/null +++ b/fuzzing/corpus/header-truncated diff --git a/fuzzing/corpus/header-v-1 b/fuzzing/corpus/header-v-1 Binary files differnew file mode 100644 index 0000000..a773d07 --- /dev/null +++ b/fuzzing/corpus/header-v-1 diff --git a/fuzzing/corpus/header-v0 b/fuzzing/corpus/header-v0 Binary files differnew file mode 100644 index 0000000..f22ec6a --- /dev/null +++ b/fuzzing/corpus/header-v0 diff --git a/fuzzing/corpus/meson-g12a-sei510-android.dtb b/fuzzing/corpus/meson-g12a-sei510-android.dtb Binary files differnew file mode 100644 index 0000000..317175d --- /dev/null +++ b/fuzzing/corpus/meson-g12a-sei510-android.dtb diff --git a/fuzzing/corpus/oob_by_one b/fuzzing/corpus/oob_by_one Binary files differnew file mode 100644 index 0000000..216523c --- /dev/null +++ b/fuzzing/corpus/oob_by_one diff --git a/fuzzing/corpus/quirks.dtb b/fuzzing/corpus/quirks.dtb Binary files differnew file mode 100644 index 0000000..676024a --- /dev/null +++ b/fuzzing/corpus/quirks.dtb diff --git a/fuzzing/libfdt_fuzzer.c b/fuzzing/libfdt_fuzzer.c index 89fe3c2..b271714 100644 --- a/fuzzing/libfdt_fuzzer.c +++ b/fuzzing/libfdt_fuzzer.c @@ -59,6 +59,24 @@ static bool phandle_is_valid(uint32_t phandle) { return phandle != 0 && phandle != UINT32_MAX; } +static void walk_node_properties(const void *device_tree, int node) { + int property, len = 0; + + fdt_for_each_property_offset(property, device_tree, node) { + const struct fdt_property *prop = fdt_get_property_by_offset(device_tree, + property, &len); + if (!prop) + continue; + check_mem(prop->data, fdt32_to_cpu(prop->len)); + + const char *prop_name = fdt_string(device_tree, prop->nameoff); + if (prop_name != NULL) { + check_mem(prop_name, strlen(prop_name)); + } + } +} + + static void walk_device_tree(const void *device_tree, int parent_node) { int len = 0; const char *node_name = fdt_get_name(device_tree, parent_node, &len); @@ -72,6 +90,30 @@ static void walk_device_tree(const void *device_tree, int parent_node) { assert(node >= 0); // it should at least find parent_node } + char path_buf[64]; + if(fdt_get_path(device_tree, parent_node, path_buf, sizeof(path_buf)) == 0) { + fdt_path_offset(device_tree, path_buf); + } + + fdt_parent_offset(device_tree, parent_node); + + // Exercise sub-node search string functions + fdt_subnode_offset(device_tree, parent_node, "a"); + fdt_get_property(device_tree, parent_node, "reg", &len); + + // Check for a stringlist node called 'stringlist' (added to corpus) + const int sl_count = fdt_stringlist_count(device_tree, + parent_node, "stringlist"); + if (sl_count > 0) { + for (int i = 0; i < sl_count; i++) { + fdt_stringlist_get(device_tree, parent_node, "stringlist", i, &len); + } + + fdt_stringlist_search(device_tree, parent_node, "stringlist", "a"); + } + + walk_node_properties(device_tree, parent_node); + // recursively walk the node's children for (int node = fdt_first_subnode(device_tree, parent_node); node >= 0; node = fdt_next_subnode(device_tree, node)) { @@ -80,15 +122,49 @@ static void walk_device_tree(const void *device_tree, int parent_node) { } +static void walk_mem_rsv(const void *device_tree) { + const int n = fdt_num_mem_rsv(device_tree); + uint64_t address, size; + + for (int i = 0; i < n; i++) { + fdt_get_mem_rsv(device_tree, i, &address, &size); + } +} + + // Information on device tree is available in external/dtc/Documentation/ // folder. int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + int rc; + // Non-zero return values are reserved for future use. if (size < FDT_V17_SIZE) return 0; - if (fdt_check_full(data, size) != 0) return 0; + // Produce coverage of checking function + rc = fdt_check_full(data, size); + fdt_strerror(rc); + // Don't continue if the library rejected the input + if (rc != 0) return 0; + + // Cover reading functions walk_device_tree(data, /* parent_node */ 0); + walk_mem_rsv(data); + + // Cover phandle functions + uint32_t phandle; + fdt_generate_phandle(data, &phandle); + + // Try and get a path by alias + fdt_path_offset(data, "a"); + + // Try to get an alias + fdt_get_alias(data, "a"); + + // Exercise common search functions + fdt_node_offset_by_compatible(data, 0, "a"); + fdt_node_offset_by_prop_value(data, 0, "x", "42", 3); return 0; } + |