diff --git a/infra/base-images/base-builder/compile_honggfuzz b/infra/base-images/base-builder/compile_honggfuzz index f86e8426d..cf206e46a 100755 --- a/infra/base-images/base-builder/compile_honggfuzz +++ b/infra/base-images/base-builder/compile_honggfuzz @@ -20,6 +20,12 @@ echo "Skipping compilation; using precompiled honggfuzz" cp $SRC/honggfuzz/honggfuzz.a $LIB_FUZZING_ENGINE cp $SRC/honggfuzz/honggfuzz $OUT/ +# Set flags necessary for netdriver compilation. +export LIB_HFND="-Wl,-u,LIBHFNETDRIVER_module_netdriver -Wl,--start-group $SRC/honggfuzz/libhfnetdriver/libhfnetdriver.a $SRC/honggfuzz/libhfcommon/libhfcommon.a -Wl,--end-group" + +export HFND_CXXFLAGS='-DHFND_FUZZING_ENTRY_FUNCTION_CXX(x,y)=extern const char* LIBHFNETDRIVER_module_netdriver;const char** LIBHFNETDRIVER_tmp1 = &LIBHFNETDRIVER_module_netdriver;extern "C" int HonggfuzzNetDriver_main(x,y);int HonggfuzzNetDriver_main(x,y)' +export HFND_CFLAGS='-DHFND_FUZZING_ENTRY_FUNCTION(x,y)=extern const char* LIBHFNETDRIVER_module_netdriver;const char** LIBHFNETDRIVER_tmp1 = &LIBHFNETDRIVER_module_netdriver;int HonggfuzzNetDriver_main(x,y);int HonggfuzzNetDriver_main(x,y)' + # Custom coverage flags, roughly in sync with: # https://github.com/google/honggfuzz/blob/oss-fuzz/hfuzz_cc/hfuzz-cc.c export COVERAGE_FLAGS="-fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp" diff --git a/infra/base-images/base-runner/run_fuzzer b/infra/base-images/base-runner/run_fuzzer index 0d8b8e07a..7eb5d46d3 100755 --- a/infra/base-images/base-runner/run_fuzzer +++ b/infra/base-images/base-runner/run_fuzzer @@ -153,6 +153,10 @@ elif [[ "$FUZZING_ENGINE" = honggfuzz ]]; then # -n: number of fuzzing threads (and processes) CMD_LINE="$OUT/honggfuzz -n 1 --exit_upon_crash -V -R /tmp/${FUZZER}_honggfuzz.report -W $FUZZER_OUT -v -z -P -f \"$CORPUS_DIR\" $(get_dictionary) $* -- \"$OUT/$FUZZER\"" + if [[ $(LC_ALL=C grep -P "\x01_LIBHFUZZ_NETDRIVER_BINARY_SIGNATURE_\x02\xFF" "$FUZZER" ) ]]; then + # Honggfuzz Netdriver port. This must match the port in Clusterfuzz. + export HFND_TCP_PORT=8666 + fi elif [[ "$FUZZING_ENGINE" = centipede ]]; then # Create the work and corpus directory for Centipede. diff --git a/projects/mongoose/Dockerfile b/projects/mongoose/Dockerfile index 15f4a4f9a..906764ca0 100644 --- a/projects/mongoose/Dockerfile +++ b/projects/mongoose/Dockerfile @@ -19,3 +19,4 @@ RUN apt-get update RUN git clone https://github.com/cesanta/mongoose WORKDIR $SRC COPY build.sh $SRC/ +COPY fuzz_netdriver_http.c $SRC/mongoose/fuzz_netdriver_http.c diff --git a/projects/mongoose/build.sh b/projects/mongoose/build.sh index 20b7be9ba..e9210d25c 100755 --- a/projects/mongoose/build.sh +++ b/projects/mongoose/build.sh @@ -13,5 +13,16 @@ # See the License for the specific language governing permissions and # limitations under the License. # + cd $SRC/mongoose $CXX $CXXFLAGS $LIB_FUZZING_ENGINE -DMG_ENABLE_LINES -DMG_ENABLE_LOG=0 mongoose.c -I. test/fuzz.c -o $OUT/fuzz + +# Fuzzer using honggfuzz netdriver. +if [[ "$FUZZING_ENGINE" == "honggfuzz" ]] +then + $CC $LIB_FUZZING_ENGINE $CFLAGS -DMG_ENABLE_LINES=1 \ + -DMG_DISABLE_DAV_AUTH -DMG_ENABLE_FAKE_DAVLOCK \ + $LIB_HFND "$HFND_CFLAGS" \ + fuzz_netdriver_http.c mongoose.c -I. -o $OUT/fuzz_netdriver_http \ + -pthread +fi diff --git a/projects/mongoose/fuzz_netdriver_http.c b/projects/mongoose/fuzz_netdriver_http.c new file mode 100644 index 000000000..8f96c1f11 --- /dev/null +++ b/projects/mongoose/fuzz_netdriver_http.c @@ -0,0 +1,30 @@ +/* Copyright 2022 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "mongoose.h" + +static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { + struct mg_http_serve_opts opts = {.root_dir = "."}; + if (ev == MG_EV_HTTP_MSG) { + // Only serve static files + mg_http_serve_dir(c, ev_data, &opts); + } +} + +HFND_FUZZING_ENTRY_FUNCTION(int argc, char **argv) { + struct mg_mgr mgr; + mg_mgr_init(&mgr); + mg_http_listen(&mgr, "http://0.0.0.0:8666", fn, &mgr); + for (;;) mg_mgr_poll(&mgr, 1000); + mg_mgr_free(&mgr); + return 0; +}