From ac02cc2886b033698f043ffed329cc102bd0c1c3 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sat, 6 Sep 2025 21:13:59 +0100 Subject: [PATCH] libcommon topic matching fuzzer --- .gitignore | 8 +++++- fuzzing/libcommon/Makefile | 14 ++++++++-- .../libcommon_fuzz_topic_matching.cpp | 28 +++++++++++++++++++ .../libcommon_fuzz_topic_matching.proto | 10 +++++++ fuzzing/scripts/oss-fuzz-build.sh | 28 +++++++++++++++++-- fuzzing/scripts/oss-fuzz-dependencies.sh | 10 ++++++- 6 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 fuzzing/libcommon/libcommon_fuzz_topic_matching.cpp create mode 100644 fuzzing/libcommon/libcommon_fuzz_topic_matching.proto diff --git a/.gitignore b/.gitignore index 629e250c..d2a75900 100644 --- a/.gitignore +++ b/.gitignore @@ -67,7 +67,6 @@ fuzzing/broker/broker_fuzz_read_handle fuzzing/broker/broker_fuzz_second_packet fuzzing/broker/broker_fuzz_second_packet_with_init fuzzing/broker/broker_fuzz_test_config - fuzzing/corpora/broker/* fuzzing/corpora/broker_packet_seed_corpus.zip fuzzing/corpora/client/* @@ -76,6 +75,13 @@ fuzzing/corpora/db_dump_seed_corpus.zip fuzzing/lib/lib_fuzz_pub_topic_check2 fuzzing/lib/lib_fuzz_sub_topic_check2 fuzzing/lib/lib_fuzz_utf8 +fuzzing/libcommon/libcommon_fuzz_pub_topic_check2 +fuzzing/libcommon/libcommon_fuzz_sub_topic_check2 +fuzzing/libcommon/libcommon_fuzz_topic_matching +fuzzing/libcommon/libcommon_fuzz_topic_matching.pb.cc +fuzzing/libcommon/libcommon_fuzz_topic_matching.pb.h +fuzzing/libcommon/libcommon_fuzz_topic_tokenise +fuzzing/libcommon/libcommon_fuzz_utf8 fuzzing/plugins/dynamic-security/dynsec_fuzz_load lib/cpp/libmosquittopp.so* diff --git a/fuzzing/libcommon/Makefile b/fuzzing/libcommon/Makefile index 5cc08be5..f8594c38 100644 --- a/fuzzing/libcommon/Makefile +++ b/fuzzing/libcommon/Makefile @@ -6,13 +6,16 @@ include ${R}/fuzzing/config.mk FUZZERS:= \ libcommon_fuzz_pub_topic_check2 \ libcommon_fuzz_sub_topic_check2 \ + libcommon_fuzz_topic_matching \ libcommon_fuzz_topic_tokenise \ libcommon_fuzz_utf8 -LOCAL_CPPFLAGS+=-I${R}/include/ -LOCAL_CXXFLAGS+=-g -Wall -Werror -pthread +LOCAL_CPPFLAGS+=-I${R}/include/ -I/usr/local/include/libprotobuf-mutator -I/src/libprotobuf-mutator/external.protobuf/include +LOCAL_CXXFLAGS+=-g -Wall -Werror -pthread -Wno-deprecated-builtins LOCAL_LDFLAGS+= LOCAL_LIBADD+=$(LIB_FUZZING_ENGINE) -lssl -lcrypto ${R}/libcommon/libmosquitto_common.a -Wl,-Bstatic -largon2 -Wl,-Bdynamic +PROTOBUF_LIBS=/usr/local/lib/libprotobuf-mutator-libfuzzer.a /usr/local/lib/libprotobuf-mutator.a /src/libprotobuf-mutator/external.protobuf/lib/*.a +PROTOC?=/src/libprotobuf-mutator/external.protobuf/bin/protoc all: $(FUZZERS) @@ -24,6 +27,13 @@ libcommon_fuzz_sub_topic_check2 : libcommon_fuzz_sub_topic_check2.cpp $(CXX) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_LDFLAGS) -o $@ $^ $(LOCAL_LIBADD) install $@ ${OUT}/$@ +libcommon_fuzz_topic_matching : libcommon_fuzz_topic_matching.cpp libcommon_fuzz_topic_matching.pb.cc + $(CXX) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_LDFLAGS) -o $@ $^ $(LOCAL_LIBADD) $(PROTOBUF_LIBS) + install $@ ${OUT}/$@ + +libcommon_fuzz_topic_matching.pb.cc : libcommon_fuzz_topic_matching.proto + $(PROTOC) --cpp_out=. $^ + libcommon_fuzz_topic_tokenise : libcommon_fuzz_topic_tokenise.cpp $(CXX) $(LOCAL_CXXFLAGS) $(LOCAL_CPPFLAGS) $(LOCAL_LDFLAGS) -o $@ $^ $(LOCAL_LIBADD) install $@ ${OUT}/$@ diff --git a/fuzzing/libcommon/libcommon_fuzz_topic_matching.cpp b/fuzzing/libcommon/libcommon_fuzz_topic_matching.cpp new file mode 100644 index 00000000..1aa21387 --- /dev/null +++ b/fuzzing/libcommon/libcommon_fuzz_topic_matching.cpp @@ -0,0 +1,28 @@ +#include "src/libfuzzer/libfuzzer_macro.h" + +#include "libcommon_fuzz_topic_matching.pb.h" +#include "mosquitto.h" + +DEFINE_PROTO_FUZZER(const fuzz_topic_matches_sub::FuzzerInput& fuzzer_input) +{ + bool result; + const char *string1 = fuzzer_input.string1().c_str(); + const char *string2 = fuzzer_input.string2().c_str(); + const char *username = nullptr; + const char *clientid = nullptr; + + if(fuzzer_input.has_username()){ + username = fuzzer_input.username().c_str(); + } + if(fuzzer_input.has_clientid()){ + clientid = fuzzer_input.clientid().c_str(); + } + + //targeted_function_1(fuzzer_input.arg1(), fuzzer_input.arg2(), fuzzer_input.arg3()); + mosquitto_topic_matches_sub(string1, string2, &result); + mosquitto_topic_matches_sub2(string1, strlen(string1), string2, strlen(string2), &result); + mosquitto_topic_matches_sub_with_pattern(string1, string2, clientid, username, &result); + + mosquitto_sub_matches_acl(string1, string2, &result); + mosquitto_sub_matches_acl_with_pattern(string1, string2, clientid, username, &result); +} diff --git a/fuzzing/libcommon/libcommon_fuzz_topic_matching.proto b/fuzzing/libcommon/libcommon_fuzz_topic_matching.proto new file mode 100644 index 00000000..c132357e --- /dev/null +++ b/fuzzing/libcommon/libcommon_fuzz_topic_matching.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +package fuzz_topic_matches_sub; + +message FuzzerInput { + required string string1 = 1; + required string string2 = 2; + optional string username = 3; + optional string clientid = 4; +} diff --git a/fuzzing/scripts/oss-fuzz-build.sh b/fuzzing/scripts/oss-fuzz-build.sh index ec3d3f30..3f040d5b 100755 --- a/fuzzing/scripts/oss-fuzz-build.sh +++ b/fuzzing/scripts/oss-fuzz-build.sh @@ -21,10 +21,32 @@ # Note that other dependencies, i.e. sqlite are not yet built because they are # only used by plugins and not currently otherwise used. cd ${SRC}/cJSON -cmake -DBUILD_SHARED_LIBS=OFF -DENABLE_CJSON_TEST=OFF -DCMAKE_C_FLAGS=-fPIC . -make +cmake \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_C_FLAGS=-fPIC \ + -DENABLE_CJSON_TEST=OFF \ + . +make -j $(nproc) +make install + +cd ${SRC}/libprotobuf-mutator +cmake \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_BUILD_TYPE=Debug \ + -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON \ + -DLIB_PROTO_MUTATOR_EXAMPLES=OFF \ + -DLIB_PROTO_MUTATOR_TESTING=OFF \ + . +make -j $(nproc) make install # Build broker and library static libraries cd ${SRC}/mosquitto -make WITH_STATIC_LIBRARIES=yes WITH_DOCS=no WITH_FUZZING=yes WITH_EDITLINE=no WITH_HTTP_API=no +make \ + WITH_STATIC_LIBRARIES=yes \ + WITH_DOCS=no \ + WITH_FUZZING=yes \ + WITH_EDITLINE=no \ + WITH_HTTP_API=no \ + -j $(nproc) diff --git a/fuzzing/scripts/oss-fuzz-dependencies.sh b/fuzzing/scripts/oss-fuzz-dependencies.sh index a6b1f411..c012ad4e 100755 --- a/fuzzing/scripts/oss-fuzz-dependencies.sh +++ b/fuzzing/scripts/oss-fuzz-dependencies.sh @@ -20,5 +20,13 @@ # Note that sqlite3 is required as a build dep of a plugin which is not # currently part of fuzz testing. Once it is part of fuzz testing, sqlite will # need to be built statically. -apt-get update && apt-get install -y libargon2-dev libedit-dev libtool-bin make libmicrohttpd-dev libsqlite3-dev +apt-get update && apt-get install -y \ + libargon2-dev \ + libedit-dev \ + liblzma-dev \ + libmicrohttpd-dev \ + libsqlite3-dev \ + libtool-bin \ + make +git clone https://github.com/google/libprotobuf-mutator ${SRC}/libprotobuf-mutator git clone https://github.com/ralight/cJSON ${SRC}/cJSON