From 3162a30858d66b819f6833b2e8f34a5d96644915 Mon Sep 17 00:00:00 2001 From: Florian Albrechtskirchinger Date: Mon, 1 Aug 2022 14:47:13 +0200 Subject: [PATCH] Move fuzzer sources to tests/fuzz/src --- tests/{ => fuzz}/src/fuzzer-driver_afl.cpp | 0 tests/{ => fuzz}/src/fuzzer-parse_bjdata.cpp | 16 +++++++++++++--- tests/{ => fuzz}/src/fuzzer-parse_bson.cpp | 16 +++++++++++++--- tests/{ => fuzz}/src/fuzzer-parse_cbor.cpp | 16 +++++++++++++--- tests/{ => fuzz}/src/fuzzer-parse_json.cpp | 16 +++++++++++++--- tests/{ => fuzz}/src/fuzzer-parse_msgpack.cpp | 16 +++++++++++++--- tests/{ => fuzz}/src/fuzzer-parse_ubjson.cpp | 16 +++++++++++++--- 7 files changed, 78 insertions(+), 18 deletions(-) rename tests/{ => fuzz}/src/fuzzer-driver_afl.cpp (100%) rename tests/{ => fuzz}/src/fuzzer-parse_bjdata.cpp (86%) rename tests/{ => fuzz}/src/fuzzer-parse_bson.cpp (81%) rename tests/{ => fuzz}/src/fuzzer-parse_cbor.cpp (80%) rename tests/{ => fuzz}/src/fuzzer-parse_json.cpp (80%) rename tests/{ => fuzz}/src/fuzzer-parse_msgpack.cpp (80%) rename tests/{ => fuzz}/src/fuzzer-parse_ubjson.cpp (86%) diff --git a/tests/src/fuzzer-driver_afl.cpp b/tests/fuzz/src/fuzzer-driver_afl.cpp similarity index 100% rename from tests/src/fuzzer-driver_afl.cpp rename to tests/fuzz/src/fuzzer-driver_afl.cpp diff --git a/tests/src/fuzzer-parse_bjdata.cpp b/tests/fuzz/src/fuzzer-parse_bjdata.cpp similarity index 86% rename from tests/src/fuzzer-parse_bjdata.cpp rename to tests/fuzz/src/fuzzer-parse_bjdata.cpp index 0ead3755f..df6facb2c 100644 --- a/tests/src/fuzzer-parse_bjdata.cpp +++ b/tests/fuzz/src/fuzzer-parse_bjdata.cpp @@ -25,12 +25,16 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer drivers. */ -#include -#include #include using json = nlohmann::json; +#ifdef __AFL_LEAK_CHECK + extern "C" void _exit(int); +#else + #define __AFL_LEAK_CHECK() do {} while(false) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) +#endif + // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -40,6 +44,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::vector vec1(data, data + size); json j1 = json::from_bjdata(vec1); + // parse errors must raise an exception and not silently result in discarded values + assert(!j1.is_discarded()); + try { // step 2.1: round trip without adding size annotations to container types @@ -64,7 +71,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) catch (const json::parse_error&) { // parsing a BJData serialization must not fail - assert(false); + __builtin_trap(); } } catch (const json::parse_error&) @@ -80,6 +87,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // out of range errors may happen if provided sizes are excessive } + // do a leak check if fuzzing with AFL++ and LSAN + __AFL_LEAK_CHECK(); + // return 0 - non-zero return values are reserved for future use return 0; } diff --git a/tests/src/fuzzer-parse_bson.cpp b/tests/fuzz/src/fuzzer-parse_bson.cpp similarity index 81% rename from tests/src/fuzzer-parse_bson.cpp rename to tests/fuzz/src/fuzzer-parse_bson.cpp index b74c39513..adeef41a8 100644 --- a/tests/src/fuzzer-parse_bson.cpp +++ b/tests/fuzz/src/fuzzer-parse_bson.cpp @@ -19,12 +19,16 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer drivers. */ -#include -#include #include using json = nlohmann::json; +#ifdef __AFL_LEAK_CHECK + extern "C" void _exit(int); +#else + #define __AFL_LEAK_CHECK() do {} while(false) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) +#endif + // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -34,6 +38,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::vector vec1(data, data + size); json j1 = json::from_bson(vec1); + // parse errors must raise an exception and not silently result in discarded values + assert(!j1.is_discarded()); + if (j1.is_discarded()) { return 0; @@ -53,7 +60,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) catch (const json::parse_error&) { // parsing a BSON serialization must not fail - assert(false); + __builtin_trap(); } } catch (const json::parse_error&) @@ -69,6 +76,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // out of range errors can occur during parsing, too } + // do a leak check if fuzzing with AFL++ and LSAN + __AFL_LEAK_CHECK(); + // return 0 - non-zero return values are reserved for future use return 0; } diff --git a/tests/src/fuzzer-parse_cbor.cpp b/tests/fuzz/src/fuzzer-parse_cbor.cpp similarity index 80% rename from tests/src/fuzzer-parse_cbor.cpp rename to tests/fuzz/src/fuzzer-parse_cbor.cpp index 187cdefe3..15d5f293e 100644 --- a/tests/src/fuzzer-parse_cbor.cpp +++ b/tests/fuzz/src/fuzzer-parse_cbor.cpp @@ -19,12 +19,16 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer drivers. */ -#include -#include #include using json = nlohmann::json; +#ifdef __AFL_LEAK_CHECK + extern "C" void _exit(int); +#else + #define __AFL_LEAK_CHECK() do {} while(false) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) +#endif + // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -34,6 +38,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::vector vec1(data, data + size); json j1 = json::from_cbor(vec1); + // parse errors must raise an exception and not silently result in discarded values + assert(!j1.is_discarded()); + try { // step 2: round trip @@ -48,7 +55,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) catch (const json::parse_error&) { // parsing a CBOR serialization must not fail - assert(false); + __builtin_trap(); } } catch (const json::parse_error&) @@ -64,6 +71,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // out of range errors can occur during parsing, too } + // do a leak check if fuzzing with AFL++ and LSAN + __AFL_LEAK_CHECK(); + // return 0 - non-zero return values are reserved for future use return 0; } diff --git a/tests/src/fuzzer-parse_json.cpp b/tests/fuzz/src/fuzzer-parse_json.cpp similarity index 80% rename from tests/src/fuzzer-parse_json.cpp rename to tests/fuzz/src/fuzzer-parse_json.cpp index 9955ee154..f5e642786 100644 --- a/tests/src/fuzzer-parse_json.cpp +++ b/tests/fuzz/src/fuzzer-parse_json.cpp @@ -20,12 +20,16 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer drivers. */ -#include -#include #include using json = nlohmann::json; +#ifdef __AFL_LEAK_CHECK + extern "C" void _exit(int); +#else + #define __AFL_LEAK_CHECK() do {} while(false) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) +#endif + // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -34,6 +38,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // step 1: parse input json j1 = json::parse(data, data + size); + // parse errors must raise an exception and not silently result in discarded values + assert(!j1.is_discarded()); + try { // step 2: round trip @@ -53,7 +60,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) catch (const json::parse_error&) { // parsing a JSON serialization must not fail - assert(false); + __builtin_trap(); } } catch (const json::parse_error&) @@ -65,6 +72,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // out of range errors may happen if provided sizes are excessive } + // do a leak check if fuzzing with AFL++ and LSAN + __AFL_LEAK_CHECK(); + // return 0 - non-zero return values are reserved for future use return 0; } diff --git a/tests/src/fuzzer-parse_msgpack.cpp b/tests/fuzz/src/fuzzer-parse_msgpack.cpp similarity index 80% rename from tests/src/fuzzer-parse_msgpack.cpp rename to tests/fuzz/src/fuzzer-parse_msgpack.cpp index 9d7c0e3b1..dd57adf01 100644 --- a/tests/src/fuzzer-parse_msgpack.cpp +++ b/tests/fuzz/src/fuzzer-parse_msgpack.cpp @@ -19,12 +19,16 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer drivers. */ -#include -#include #include using json = nlohmann::json; +#ifdef __AFL_LEAK_CHECK + extern "C" void _exit(int); +#else + #define __AFL_LEAK_CHECK() do {} while(false) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) +#endif + // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -34,6 +38,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::vector vec1(data, data + size); json j1 = json::from_msgpack(vec1); + // parse errors must raise an exception and not silently result in discarded values + assert(!j1.is_discarded()); + try { // step 2: round trip @@ -48,7 +55,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) catch (const json::parse_error&) { // parsing a MessagePack serialization must not fail - assert(false); + __builtin_trap(); } } catch (const json::parse_error&) @@ -64,6 +71,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // out of range errors may happen if provided sizes are excessive } + // do a leak check if fuzzing with AFL++ and LSAN + __AFL_LEAK_CHECK(); + // return 0 - non-zero return values are reserved for future use return 0; } diff --git a/tests/src/fuzzer-parse_ubjson.cpp b/tests/fuzz/src/fuzzer-parse_ubjson.cpp similarity index 86% rename from tests/src/fuzzer-parse_ubjson.cpp rename to tests/fuzz/src/fuzzer-parse_ubjson.cpp index b40300154..37543528c 100644 --- a/tests/src/fuzzer-parse_ubjson.cpp +++ b/tests/fuzz/src/fuzzer-parse_ubjson.cpp @@ -25,12 +25,16 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer drivers. */ -#include -#include #include using json = nlohmann::json; +#ifdef __AFL_LEAK_CHECK + extern "C" void _exit(int); +#else + #define __AFL_LEAK_CHECK() do {} while(false) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) +#endif + // see http://llvm.org/docs/LibFuzzer.html extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { @@ -40,6 +44,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) std::vector vec1(data, data + size); json j1 = json::from_ubjson(vec1); + // parse errors must raise an exception and not silently result in discarded values + assert(!j1.is_discarded()); + try { // step 2.1: round trip without adding size annotations to container types @@ -64,7 +71,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) catch (const json::parse_error&) { // parsing a UBJSON serialization must not fail - assert(false); + __builtin_trap(); } } catch (const json::parse_error&) @@ -80,6 +87,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) // out of range errors may happen if provided sizes are excessive } + // do a leak check if fuzzing with AFL++ and LSAN + __AFL_LEAK_CHECK(); + // return 0 - non-zero return values are reserved for future use return 0; }