diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bd22057..0cb3342 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 0000000..cca74fd --- /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 0000000..b4e009d Binary files /dev/null and b/tests/fuzz/corpus/71520a5c4b5ca73903216857abbad54a8002d44a differ diff --git a/tests/fuzz/corpus/c1dfd96eea8cc2b62785275bca38ac261256e278 b/tests/fuzz/corpus/c1dfd96eea8cc2b62785275bca38ac261256e278 new file mode 100644 index 0000000..62f9457 --- /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 0000000..3d70d85 Binary files /dev/null and b/tests/fuzz/corpus/c42ac1c46f1d4e211c735cc7dfad4ff8391110e9 differ diff --git a/tests/fuzz/corpus/valid-blobmsg.bin b/tests/fuzz/corpus/valid-blobmsg.bin new file mode 100644 index 0000000..2d0c68e Binary files /dev/null and b/tests/fuzz/corpus/valid-blobmsg.bin differ diff --git a/tests/fuzz/test-fuzz.c b/tests/fuzz/test-fuzz.c new file mode 100644 index 0000000..7153847 --- /dev/null +++ b/tests/fuzz/test-fuzz.c @@ -0,0 +1,76 @@ +#include +#include +#include + +#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; +}