[OpenWrt-Devel] [PATCH libubox 05/20] tests: add libFuzzer based tests

Petr Štetiar ynezz at true.cz
Thu Dec 19 16:58:21 EST 2019


LibFuzzer is in-process, coverage-guided, evolutionary fuzzing engine.

LibFuzzer is linked with the library under test, and feeds fuzzed inputs
to the library via a specific fuzzing entrypoint (aka "target
function"); the fuzzer then tracks which areas of the code are reached,
and generates mutations on the corpus of input data in order to maximize
the code coverage.

Lets use libFuzzer to fuzz blob and blobmsg parsing for the start.

Ref: https://llvm.org/docs/LibFuzzer.html
Signed-off-by: Petr Štetiar <ynezz at true.cz>
---
 tests/CMakeLists.txt                          |   4 +
 tests/fuzz/CMakeLists.txt                     |  18 +++++
 .../71520a5c4b5ca73903216857abbad54a8002d44a  | Bin 0 -> 2 bytes
 .../c1dfd96eea8cc2b62785275bca38ac261256e278  |   1 +
 .../c42ac1c46f1d4e211c735cc7dfad4ff8391110e9  | Bin 0 -> 3 bytes
 tests/fuzz/corpus/valid-blobmsg.bin           | Bin 0 -> 176 bytes
 tests/fuzz/test-fuzz.c                        |  76 ++++++++++++++++++
 7 files changed, 99 insertions(+)
 create mode 100644 tests/fuzz/CMakeLists.txt
 create mode 100644 tests/fuzz/corpus/71520a5c4b5ca73903216857abbad54a8002d44a
 create mode 100644 tests/fuzz/corpus/c1dfd96eea8cc2b62785275bca38ac261256e278
 create mode 100644 tests/fuzz/corpus/c42ac1c46f1d4e211c735cc7dfad4ff8391110e9
 create mode 100644 tests/fuzz/corpus/valid-blobmsg.bin
 create mode 100644 tests/fuzz/test-fuzz.c

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index bd2205743318..0cb33427e45a 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -12,3 +12,7 @@ FOREACH(test_case ${test_cases})
   ADD_UNIT_TEST(${test_case})
   ADD_UNIT_TEST_SAN(${test_case})
 ENDFOREACH(test_case)
+
+IF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+  ADD_SUBDIRECTORY(fuzz)
+ENDIF()
diff --git a/tests/fuzz/CMakeLists.txt b/tests/fuzz/CMakeLists.txt
new file mode 100644
index 000000000000..cca74fd6ca12
--- /dev/null
+++ b/tests/fuzz/CMakeLists.txt
@@ -0,0 +1,18 @@
+FILE(GLOB test_cases "test-*.c")
+
+MACRO(ADD_FUZZER_TEST name)
+  ADD_EXECUTABLE(${name} ${name}.c)
+  TARGET_COMPILE_OPTIONS(${name} PRIVATE -g -O1 -fno-omit-frame-pointer -fsanitize=fuzzer,address,leak,undefined)
+  TARGET_INCLUDE_DIRECTORIES(${name} PRIVATE ${PROJECT_SOURCE_DIR})
+  TARGET_LINK_OPTIONS(${name} PRIVATE -stdlib=libc++ -fsanitize=fuzzer,address,leak,undefined)
+  TARGET_LINK_LIBRARIES(${name} ubox blobmsg_json json_script ${json})
+  ADD_TEST(
+    NAME ${name}
+    COMMAND ${name} -max_len=256 -timeout=10 -max_total_time=300 ${CMAKE_CURRENT_SOURCE_DIR}/corpus
+  )
+ENDMACRO(ADD_FUZZER_TEST)
+
+FOREACH(test_case ${test_cases})
+  GET_FILENAME_COMPONENT(test_case ${test_case} NAME_WE)
+  ADD_FUZZER_TEST(${test_case})
+ENDFOREACH(test_case)
diff --git a/tests/fuzz/corpus/71520a5c4b5ca73903216857abbad54a8002d44a b/tests/fuzz/corpus/71520a5c4b5ca73903216857abbad54a8002d44a
new file mode 100644
index 0000000000000000000000000000000000000000..b4e009dd6d7e91ff56595a84010db2eb81e41622
GIT binary patch
literal 2
Jcmcb}0004`0MY;e

literal 0
HcmV?d00001

diff --git a/tests/fuzz/corpus/c1dfd96eea8cc2b62785275bca38ac261256e278 b/tests/fuzz/corpus/c1dfd96eea8cc2b62785275bca38ac261256e278
new file mode 100644
index 000000000000..62f9457511f8
--- /dev/null
+++ b/tests/fuzz/corpus/c1dfd96eea8cc2b62785275bca38ac261256e278
@@ -0,0 +1 @@
+6
\ No newline at end of file
diff --git a/tests/fuzz/corpus/c42ac1c46f1d4e211c735cc7dfad4ff8391110e9 b/tests/fuzz/corpus/c42ac1c46f1d4e211c735cc7dfad4ff8391110e9
new file mode 100644
index 0000000000000000000000000000000000000000..3d70d85eba81360f757bc71859316667610c5339
GIT binary patch
literal 3
KcmZQ%U<3dF2LJ;A

literal 0
HcmV?d00001

diff --git a/tests/fuzz/corpus/valid-blobmsg.bin b/tests/fuzz/corpus/valid-blobmsg.bin
new file mode 100644
index 0000000000000000000000000000000000000000..2d0c68e8a1273ae12ac6d4401c7471927809a926
GIT binary patch
literal 176
zcmZo>V31>A&rK~ZPE1c_U|{e_&B at 8vQ7F$Z%1KcK@*9Cd3 at kaB#U%_3tqcr2Kp`+d
zVlyJKnK~F4BpBFI@=KF)K*ljRBy39qfhLeS93`p6B`Jv|i3|+5)B(*BU|`JvxdNn}
Rv6+E^kAW5J90ntx007e$BMSfk

literal 0
HcmV?d00001

diff --git a/tests/fuzz/test-fuzz.c b/tests/fuzz/test-fuzz.c
new file mode 100644
index 000000000000..7153847e0825
--- /dev/null
+++ b/tests/fuzz/test-fuzz.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+
+#include "blob.h"
+#include "blobmsg.h"
+
+static void fuzz_blobmsg_parse(const uint8_t *data, size_t size)
+{
+	enum {
+		FOO_MESSAGE,
+		FOO_LIST,
+		FOO_TESTDATA,
+		__FOO_MAX
+	};
+
+	static const struct blobmsg_policy foo_policy[] = {
+		[FOO_MESSAGE] = {
+			.name = "message",
+			.type = BLOBMSG_TYPE_STRING,
+		},
+		[FOO_LIST] = {
+			.name = "list",
+			.type = BLOBMSG_TYPE_ARRAY,
+		},
+		[FOO_TESTDATA] = {
+			.name = "testdata",
+			.type = BLOBMSG_TYPE_TABLE,
+		},
+	};
+
+	struct blob_attr *tb[__FOO_MAX];
+
+	blobmsg_parse(foo_policy, __FOO_MAX, tb, (uint8_t *)data, size);
+	blobmsg_parse_array(foo_policy, __FOO_MAX, tb, (uint8_t *)data, size);
+}
+
+static void fuzz_blob_parse(const uint8_t *data, size_t size)
+{
+	enum {
+		FOO_ATTR_NESTED,
+		FOO_ATTR_BINARY,
+		FOO_ATTR_STRING,
+		FOO_ATTR_INT8,
+		FOO_ATTR_INT16,
+		FOO_ATTR_INT32,
+		FOO_ATTR_INT64,
+		FOO_ATTR_DOUBLE,
+		__FOO_ATTR_MAX
+	};
+
+
+	static const struct blob_attr_info foo_policy[__FOO_ATTR_MAX] = {
+		[FOO_ATTR_NESTED] = { .type = BLOB_ATTR_NESTED },
+		[FOO_ATTR_BINARY] = { .type = BLOB_ATTR_BINARY },
+		[FOO_ATTR_STRING] = { .type = BLOB_ATTR_STRING },
+		[FOO_ATTR_INT8] = { .type = BLOB_ATTR_INT8 },
+		[FOO_ATTR_INT16] = { .type = BLOB_ATTR_INT16 },
+		[FOO_ATTR_INT32] = { .type = BLOB_ATTR_INT32 },
+		[FOO_ATTR_INT64] = { .type = BLOB_ATTR_INT64 },
+		[FOO_ATTR_DOUBLE] = { .type = BLOB_ATTR_DOUBLE },
+	};
+
+	struct blob_attr *foo[__FOO_ATTR_MAX];
+	struct blob_attr *buf = (struct blob_attr *)data;
+
+	blob_parse(buf, foo, foo_policy, __FOO_ATTR_MAX);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+	fuzz_blob_parse(data, size);
+	fuzz_blobmsg_parse(data, size);
+
+	return 0;
+}

_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list