aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Clément Tosi <ptosi@google.com>2023-10-12 22:28:58 +0100
committerPierre-Clément Tosi <ptosi@google.com>2023-10-12 22:33:06 +0100
commitc566e548af7dd8df8f17ce1d3fc3b8317de8b249 (patch)
treea754c6f4a1babf890fe0800616ee08d9d45f7439
parent0e7797a53c131f9174d4f3a41cab04b477def75a (diff)
downloaddtc-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.bp1
-rw-r--r--fuzzing/corpus/crash-a5b94d95681291f3057eea7f0233c8f1529b2f59bin0 -> 1369 bytes
-rw-r--r--fuzzing/corpus/hardy-octopusbin0 -> 1171 bytes
-rw-r--r--fuzzing/corpus/header-truncatedbin0 -> 40 bytes
-rw-r--r--fuzzing/corpus/header-v-1bin0 -> 40 bytes
-rw-r--r--fuzzing/corpus/header-v0bin0 -> 40 bytes
-rw-r--r--fuzzing/corpus/meson-g12a-sei510-android.dtbbin0 -> 1363 bytes
-rw-r--r--fuzzing/corpus/oob_by_onebin0 -> 256 bytes
-rw-r--r--fuzzing/corpus/quirks.dtbbin0 -> 327 bytes
-rw-r--r--fuzzing/libfdt_fuzzer.c78
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
new file mode 100644
index 0000000..dbab42e
--- /dev/null
+++ b/fuzzing/corpus/crash-a5b94d95681291f3057eea7f0233c8f1529b2f59
Binary files differ
diff --git a/fuzzing/corpus/hardy-octopus b/fuzzing/corpus/hardy-octopus
new file mode 100644
index 0000000..81615e9
--- /dev/null
+++ b/fuzzing/corpus/hardy-octopus
Binary files differ
diff --git a/fuzzing/corpus/header-truncated b/fuzzing/corpus/header-truncated
new file mode 100644
index 0000000..1db29d8
--- /dev/null
+++ b/fuzzing/corpus/header-truncated
Binary files differ
diff --git a/fuzzing/corpus/header-v-1 b/fuzzing/corpus/header-v-1
new file mode 100644
index 0000000..a773d07
--- /dev/null
+++ b/fuzzing/corpus/header-v-1
Binary files differ
diff --git a/fuzzing/corpus/header-v0 b/fuzzing/corpus/header-v0
new file mode 100644
index 0000000..f22ec6a
--- /dev/null
+++ b/fuzzing/corpus/header-v0
Binary files differ
diff --git a/fuzzing/corpus/meson-g12a-sei510-android.dtb b/fuzzing/corpus/meson-g12a-sei510-android.dtb
new file mode 100644
index 0000000..317175d
--- /dev/null
+++ b/fuzzing/corpus/meson-g12a-sei510-android.dtb
Binary files differ
diff --git a/fuzzing/corpus/oob_by_one b/fuzzing/corpus/oob_by_one
new file mode 100644
index 0000000..216523c
--- /dev/null
+++ b/fuzzing/corpus/oob_by_one
Binary files differ
diff --git a/fuzzing/corpus/quirks.dtb b/fuzzing/corpus/quirks.dtb
new file mode 100644
index 0000000..676024a
--- /dev/null
+++ b/fuzzing/corpus/quirks.dtb
Binary files differ
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;
}
+