[automerger skipped] Merge "Fix integer wrap sanitisation." into sc-dev am: c8e7fc5297 -s ours am: ca907770de -s ours
am skip reason: Merged-In I232155e7f7a54271a6a3e3a7cd91ed6bbabc051f with SHA-1 2b597691ef is already in history
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/dtc/+/19606333
Change-Id: I65ca31f74288a062dbd69b509e72abb0508fbe8c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/fuzzing/Android.bp b/fuzzing/Android.bp
new file mode 100644
index 0000000..ddda130
--- /dev/null
+++ b/fuzzing/Android.bp
@@ -0,0 +1,15 @@
+// Copyright 2022 The Android Open Source Project
+package {
+ default_applicable_licenses: ["external_dtc_license"],
+}
+
+cc_fuzz {
+ name: "libfdt_fuzzer",
+ srcs: [
+ "libfdt_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libfdt",
+ ],
+ host_supported: true,
+}
diff --git a/fuzzing/libfdt_fuzzer.cpp b/fuzzing/libfdt_fuzzer.cpp
new file mode 100644
index 0000000..4a0b1fc
--- /dev/null
+++ b/fuzzing/libfdt_fuzzer.cpp
@@ -0,0 +1,42 @@
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libfdt.h"
+#include "libfdt_env.h"
+
+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);
+ if (node_name != NULL) {
+ // avoid clang complaining about unused variable node_name and force
+ // ASan to validate string pointer in strlen call.
+ assert(strlen(node_name) == len);
+ }
+
+ uint32_t phandle = fdt_get_phandle(device_tree, parent_node);
+ if (phandle != 0) {
+ assert(parent_node == fdt_node_offset_by_phandle(device_tree, phandle));
+ }
+
+ // 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)) {
+ walk_device_tree(device_tree, node);
+ }
+}
+
+// Information on device tree is available in external/dtc/Documentation/
+// folder.
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ // Non-zero return values are reserved for future use.
+ if (size < FDT_V17_SIZE) return 0;
+
+ if (fdt_check_header(data) != 0) return 0;
+
+ int root_node_offset = 0;
+ walk_device_tree(data, root_node_offset);
+
+ return 0;
+}
\ No newline at end of file