From: Andrei Pavel Date: Tue, 3 Mar 2026 14:48:56 +0000 (+0200) Subject: [#4272] Integrate the Ada Logics fuzzing harnesses into the Meson build system X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2da476253a37aa3f417d0ffb3f15376be6233281;p=thirdparty%2Fkea.git [#4272] Integrate the Ada Logics fuzzing harnesses into the Meson build system --- diff --git a/src/fuzz/build.sh b/src/fuzz/build.sh index 57b9cec6c2..4104cab337 100755 --- a/src/fuzz/build.sh +++ b/src/fuzz/build.sh @@ -1,4 +1,5 @@ #!/bin/bash -eu + # Copyright (C) 2025 Ada Logics Ltd. # # This Source Code Form is subject to the terms of the Mozilla Public @@ -6,14 +7,16 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. ################################################################################ +# This file is required by OSS-Fuzz. + # Compile log4cplus -cd $SRC/log4cplus +cd "${SRC}/log4cplus" ./configure --prefix=/usr --enable-static --disable-shared --with-pic make -j"$(nproc)" make install # Configure flags -cd $SRC/kea +cd "${SRC}/kea" export CXXFLAGS="${CXXFLAGS:-} -gdwarf-4" export LDFLAGS="${LDFLAGS:-} -gdwarf-4" @@ -33,6 +36,9 @@ else CPP_ARGS="${CPP_ARGS} -fsanitize=fuzzer-no-link" fi +# shellcheck disable=SC2086 +# SC2086: Double quote to prevent globbing and word splitting. +# Reason: we specifically want ${SANITIZER_CHOICE} to split because there may be multiple words in it. meson setup build --prefix="$OUT" $SANITIZER_CHOICE -D cpp_std=c++17 \ -D fuzz=enabled -D tests=enabled -D crypto=openssl -D default_library=static \ -D default_both_libraries=static -D cpp_args="$CPP_ARGS" -D cpp_link_args="$LD_ARGS" \ @@ -40,16 +46,16 @@ meson setup build --prefix="$OUT" $SANITIZER_CHOICE -D cpp_std=c++17 \ meson compile --verbose -C build # Package static library -find $SRC/kea/build/src/lib -type f -name '*.o' -print0 | xargs -0 llvm-ar rcsD libkea.a +find "${SRC}/kea/build/src/lib" -type f -name '*.o' -print0 | xargs -0 llvm-ar rcsD libkea.a llvm-ranlib libkea.a # Find necessary static libraries BUILD_BASEDIR="$SRC/kea/build/src" KEA_STATIC_LIBS="/usr/lib/liblog4cplus.a libkea.a " -KEA_STATIC_LIBS+=$(find $BUILD_BASEDIR/bin \( -path '/src/kea/build/src/bin/dhcp4/*' -o -path '/src/kea/build/src/bin/dhcp6/*' \) -prune -o -type f -name '*.a' -print) +KEA_STATIC_LIBS+=$(find "${BUILD_BASEDIR}/bin" \( -path '/src/kea/build/src/bin/dhcp4/*' -o -path '/src/kea/build/src/bin/dhcp6/*' \) -prune -o -type f -name '*.a' -print) KEA_STATIC_LIBS_TEST="$KEA_STATIC_LIBS $SRC/kea/build/subprojects/googletest-1.15.2/googletest/libgtest-all.a" -INCLUDES="-I. -I$SRC -I$SRC/kea-fuzzer -Isrc -Ibuild -Isrc/lib -Isrc/bin -Isrc/hooks -Isrc/hooks/d2 -Isrc/hooks/d2/gss_tsig " +INCLUDES="-I. -I$SRC -I$SRC/kea/src/fuzz -Isrc -Ibuild -Isrc/lib -Isrc/bin -Isrc/hooks -Isrc/hooks/d2 -Isrc/hooks/d2/gss_tsig " INCLUDES+="-Isrc/hooks/dhcp/pgsql -Isrc/hooks/dhcp/mysql -Isrc/hooks/dhcp/user_chk -I/usr/include/postgresql -I/usr/include/mariadb" KEA_INCLUDES="$INCLUDES -I/src/kea/subprojects/googletest-1.15.2/googletest/include -Ifuzz" LIBS="-lpthread -ldl -lm -lc++ -lc++abi -lssl -lcrypto -lkrb5 -lgssapi_krb5" @@ -63,21 +69,27 @@ do extra_lib="$SRC/kea/build/src/hooks/d2/gss_tsig/libddns_gss_tsig.a" ;; esac - + # fuzz_dns, fuzz_encode, and fuzz_cryptolink don't need helper_func.cc if [ "$fuzzer" = "fuzz_dns" ] || [ "$fuzzer" = "fuzz_encode" ] || [ "$fuzzer" = "fuzz_cryptolink" ]; then - $CXX $CXXFLAGS "$SRC/kea-fuzzer/${fuzzer}.cc" \ + # shellcheck disable=SC2086 + # SC2086: Double quote to prevent globbing and word splitting. + # Reason: we specifically want several variables to split because there may be multiple words in it. + $CXX $CXXFLAGS "$SRC/kea/src/fuzz/${fuzzer}.cc" \ -Wl,--start-group $KEA_STATIC_LIBS $extra_lib -Wl,--end-group \ $INCLUDES $LIBS $LIB_FUZZING_ENGINE -o "$OUT/${fuzzer}" else - $CXX $CXXFLAGS "$SRC/kea-fuzzer/helper_func.cc" \ - "$SRC/kea-fuzzer/${fuzzer}.cc" \ + # shellcheck disable=SC2086 + # SC2086: Double quote to prevent globbing and word splitting. + # Reason: we specifically want several variables to split because there may be multiple words in it. + $CXX $CXXFLAGS "$SRC/kea/src/fuzz/helper_func.cc" \ + "$SRC/kea/src/fuzz/${fuzzer}.cc" \ -Wl,--start-group $KEA_STATIC_LIBS $extra_lib -Wl,--end-group \ $INCLUDES $LIBS $LIB_FUZZING_ENGINE -o "$OUT/${fuzzer}" fi - if [ -f "$SRC/kea-fuzzer/${fuzzer}.dict" ]; then - cp $SRC/kea-fuzzer/${fuzzer}.dict $OUT + if [ -f "$SRC/kea/src/fuzz/${fuzzer}.dict" ]; then + cp "${SRC}/kea/src/fuzz/${fuzzer}.dict" "${OUT}" fi done @@ -90,59 +102,62 @@ do do extra_lib="" case "$fuzzer" in fuzz_pgsql) - extra_lib="$SRC/kea-fuzzer/pgmock.cc " + extra_lib="$SRC/kea/src/fuzz/pgmock.cc " extra_lib+="$SRC/kea/build/src/hooks/dhcp/pgsql/libdhcp_pgsql.a" ;; esac case "$fuzzer" in fuzz_mysql) - extra_lib="$SRC/kea-fuzzer/mysqlmock.cc " + extra_lib="$SRC/kea/src/fuzz/mysqlmock.cc " extra_lib+="$SRC/kea/build/src/hooks/dhcp/mysql/libdhcp_mysql.a" ;; esac case "$fuzzer" in fuzz_dhcp_pkt_process) extra_lib="$SRC/kea/build/src/hooks/dhcp/lease_cmds/libdhcp_lease_cmds.a" - cp $SRC/kea-fuzzer/fuzz_dhcp_pkt.dict $OUT/${fuzzer}${DHCPVER}.dict + cp "${SRC}/kea/src/fuzz/fuzz_dhcp_pkt.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" ;; esac case "$fuzzer" in fuzz_hook_run_script) extra_lib="$SRC/kea/build/src/hooks/dhcp/run_script/libdhcp_run_script.a" - cp $SRC/kea-fuzzer/fuzz_dhcp_pkt.dict $OUT/${fuzzer}${DHCPVER}.dict + cp "${SRC}/kea/src/fuzz/fuzz_dhcp_pkt.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" ;; esac case "$fuzzer" in fuzz_hook_radius) extra_lib="$SRC/kea/build/src/hooks/dhcp/radius/libdhcp_radius.a" - cp $SRC/kea-fuzzer/fuzz_dhcp_pkt.dict $OUT/${fuzzer}${DHCPVER}.dict + cp "${SRC}/kea/src/fuzz/fuzz_dhcp_pkt.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" ;; esac case "$fuzzer" in fuzz_hook_ddns_tuning) extra_lib="$SRC/kea/build/src/hooks/dhcp/ddns_tuning/libdhcp_ddns_tuning.a" - cp $SRC/kea-fuzzer/fuzz_dhcp_pkt.dict $OUT/${fuzzer}${DHCPVER}.dict + cp "${SRC}/kea/src/fuzz/fuzz_dhcp_pkt.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" ;; esac case "$fuzzer" in fuzz_hook_lease_query) extra_lib="$SRC/kea/build/src/hooks/dhcp/lease_query/libdhcp_lease_query.a" - cp $SRC/kea-fuzzer/fuzz_dhcp_pkt.dict $OUT/${fuzzer}${DHCPVER}.dict + cp "${SRC}/kea/src/fuzz/fuzz_dhcp_pkt.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" ;; esac case "$fuzzer" in fuzz_hook_flex_id) extra_lib="$SRC/kea/build/src/hooks/dhcp/flex_id/libdhcp_flex_id.a" - cp $SRC/kea-fuzzer/fuzz_dhcp_pkt.dict $OUT/${fuzzer}${DHCPVER}.dict + cp "${SRC}/kea/src/fuzz/fuzz_dhcp_pkt.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" ;; esac case "$fuzzer" in fuzz_hook_user_chk) extra_lib="$SRC/kea/build/src/hooks/dhcp/user_chk/libdhcp_user_chk.a" - cp $SRC/kea-fuzzer/fuzz_dhcp_pkt.dict $OUT/${fuzzer}${DHCPVER}.dict + cp "${SRC}/kea/src/fuzz/fuzz_dhcp_pkt.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" ;; esac - $CXX $CXXFLAGS -Wl,--start-group "$SRC/kea-fuzzer/helper_func.cc" \ - "$SRC/kea-fuzzer/${fuzzer}${DHCPVER}.cc" $extra_lib \ + # shellcheck disable=SC2086 + # SC2086: Double quote to prevent globbing and word splitting. + # Reason: we specifically want several variables to split because there may be multiple words in it. + $CXX $CXXFLAGS -Wl,--start-group "$SRC/kea/src/fuzz/helper_func.cc" \ + "$SRC/kea/src/fuzz/${fuzzer}${DHCPVER}.cc" $extra_lib \ $KEA_STATIC_LIBS $BUILD_BASEDIR/bin/dhcp$DHCPVER/libdhcp$DHCPVER.a \ -Wl,--end-group $INCLUDES $LIBS \ $LIB_FUZZING_ENGINE -o "$OUT/${fuzzer}${DHCPVER}" - if [ -f "$SRC/kea-fuzzer/${fuzzer}.dict" ]; then - cp $SRC/kea-fuzzer/${fuzzer}.dict $OUT/${fuzzer}${DHCPVER}.dict + if [ -f "$SRC/kea/src/fuzz/${fuzzer}.dict" ]; then + cp "${SRC}/kea/src/fuzz/${fuzzer}.dict" "${OUT}/${fuzzer}${DHCPVER}.dict" fi done @@ -154,8 +169,11 @@ do continue fi - $CXX $CXXFLAGS -Wl,--start-group "$SRC/kea/fuzz/${fuzzer}${DHCPVER}.cc" \ - $SRC/kea/fuzz/fuzz.cc $KEA_STATIC_LIBS_TEST \ + # shellcheck disable=SC2086 + # SC2086: Double quote to prevent globbing and word splitting. + # Reason: we specifically want several variables to split because there may be multiple words in it. + $CXX $CXXFLAGS -Wl,--start-group "$SRC/kea/src/fuzz/${fuzzer}${DHCPVER}.cc" \ + $SRC/kea/src/fuzz/fuzz.cc $KEA_STATIC_LIBS_TEST \ $BUILD_BASEDIR/bin/dhcp$DHCPVER/libdhcp$DHCPVER.a \ $KEA_INCLUDES $LIBS $LIB_FUZZING_ENGINE -Wl,--end-group \ -o "$OUT/${fuzzer}${DHCPVER}" @@ -167,12 +185,12 @@ for fuzzer in fuzz_eval4 fuzz_eval6 fuzz_dhcp_parser4 fuzz_dhcp_parser6 \ fuzz_dhcp_pkt4 fuzz_dhcp_pkt6 fuzz_cc fuzz_d2 fuzz_agent \ fuzz_config_kea_dhcp4 fuzz_config_kea_dhcp6 do - echo -e "[libfuzzer]\nmax_len=25600" > $OUT/$fuzzer.options + printf '[libfuzzer]\nmax_len=25600\n' > "${OUT}/${fuzzer}.options" done # Prepare the seeds -zip -j $OUT/fuzz_dhcpsrv_seed_corpus.zip $SRC/kea-fuzzer/corp/*.json -zip -j $OUT/fuzz_dhcp_parser4_seed_corpus.zip $SRC/kea-fuzzer/corp/*.json -zip -j $OUT/fuzz_dhcp_parser6_seed_corpus.zip $SRC/kea-fuzzer/corp/*.json -zip -j $OUT/fuzz_agent_seed_corpus.zip $SRC/kea/src/bin/agent/tests/testdata/*.json -zip -j $OUT/fuzz_d2_seed_corpus.zip $SRC/kea/src/bin/d2/tests/testdata/*.json +zip -j "${OUT}/fuzz_dhcpsrv_seed_corpus.zip" "${SRC}/kea/src/fuzz/corp"/*.json +zip -j "${OUT}/fuzz_dhcp_parser4_seed_corpus.zip" "${SRC}/kea/src/fuzz/corp"/*.json +zip -j "${OUT}/fuzz_dhcp_parser6_seed_corpus.zip" "${SRC}/kea/src/fuzz/corp"/*.json +zip -j "${OUT}/fuzz_agent_seed_corpus.zip" "${SRC}/kea/src/bin/agent/tests/testdata"/*.json +zip -j "${OUT}/fuzz_d2_seed_corpus.zip" "${SRC}/kea/src/bin/d2/tests/testdata"/*.json diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp4/dhcp-payload-only b/src/fuzz/corp/dhcp-payload-only.pkt4 similarity index 100% rename from src/fuzz/input/fuzz_packets_kea_dhcp4/dhcp-payload-only rename to src/fuzz/corp/dhcp-payload-only.pkt4 diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp6/dhcp-payload-only b/src/fuzz/corp/dhcp-payload-only.pkt6 similarity index 100% rename from src/fuzz/input/fuzz_packets_kea_dhcp6/dhcp-payload-only rename to src/fuzz/corp/dhcp-payload-only.pkt6 diff --git a/src/fuzz/corp/doc-examples4 b/src/fuzz/corp/doc-examples4 new file mode 120000 index 0000000000..0b5652bef7 --- /dev/null +++ b/src/fuzz/corp/doc-examples4 @@ -0,0 +1 @@ +../../../doc/examples/kea4 \ No newline at end of file diff --git a/src/fuzz/corp/doc-examples6 b/src/fuzz/corp/doc-examples6 new file mode 120000 index 0000000000..05f98b3048 --- /dev/null +++ b/src/fuzz/corp/doc-examples6 @@ -0,0 +1 @@ +../../../doc/examples/kea6 \ No newline at end of file diff --git a/src/fuzz/input/fuzz_config_kea_dhcp4/empty b/src/fuzz/corp/empty similarity index 100% rename from src/fuzz/input/fuzz_config_kea_dhcp4/empty rename to src/fuzz/corp/empty diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp4/full-dhcp-packet b/src/fuzz/corp/full-dhcp-packet.pkt4 similarity index 100% rename from src/fuzz/input/fuzz_packets_kea_dhcp4/full-dhcp-packet rename to src/fuzz/corp/full-dhcp-packet.pkt4 diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp6/full-dhcp-packet b/src/fuzz/corp/full-dhcp-packet.pkt6 similarity index 100% rename from src/fuzz/input/fuzz_packets_kea_dhcp6/full-dhcp-packet rename to src/fuzz/corp/full-dhcp-packet.pkt6 diff --git a/src/fuzz/corp/leases.csv b/src/fuzz/corp/leases.csv index ddd05f2998..67b63e4ee8 100644 --- a/src/fuzz/corp/leases.csv +++ b/src/fuzz/corp/leases.csv @@ -1,3 +1,3 @@ lease_id,ip_address,subnet_id,state,valid_since,valid_until,mac_address,client_id,hostname 1,192.168.1.100,1,0,2023-10-27 10:00:00,2023-10-27 11:00:00,00:11:22:33:44:55,None,device1 -2,192.168.1.101,1,0,2023-10-27 10:05:00,2023-10-27 11:05:00,AA:BB:CC:DD:EE:FF,None,device2 \ No newline at end of file +2,192.168.1.101,1,0,2023-10-27 10:05:00,2023-10-27 11:05:00,AA:BB:CC:DD:EE:FF,None,device2 diff --git a/src/fuzz/corp/meson.build b/src/fuzz/corp/meson.build new file mode 100644 index 0000000000..5a2cc56c94 --- /dev/null +++ b/src/fuzz/corp/meson.build @@ -0,0 +1,6 @@ +# Copy corp to build directory so that tests can find it. +current_source_dir = meson.current_source_dir() +command = run_command(GRABBER, current_source_dir, '*', check: true) +foreach j : command.stdout().strip().split('\n') + configure_file(input: j, output: j, copy: true) +endforeach diff --git a/src/fuzz/input/fuzz_config_kea_dhcp4/one-byte b/src/fuzz/corp/one-byte similarity index 100% rename from src/fuzz/input/fuzz_config_kea_dhcp4/one-byte rename to src/fuzz/corp/one-byte diff --git a/src/fuzz/corp/sample.csv b/src/fuzz/corp/sample.csv index 05f6c715e6..6790eadcd5 100644 --- a/src/fuzz/corp/sample.csv +++ b/src/fuzz/corp/sample.csv @@ -48,4 +48,4 @@ EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMM 137,Renske,Ladwig,RLADWIG,650.121.1234,14-JUL-03,ST_CLERK,3600, - ,123,50 138,Stephen,Stiles,SSTILES,650.121.2034,26-OCT-05,ST_CLERK,3200, - ,123,50 139,John,Seo,JSEO,650.121.2019,12-FEB-06,ST_CLERK,2700, - ,123,50 -140,Joshua,Patel,JPATEL,650.121.1834,06-APR-06,ST_CLERK,2500, - ,123,50 \ No newline at end of file +140,Joshua,Patel,JPATEL,650.121.1834,06-APR-06,ST_CLERK,2500, - ,123,50 diff --git a/src/fuzz/corp/sample2.json b/src/fuzz/corp/sample2.json index 9eea6ad6ea..d31a395bd4 100644 --- a/src/fuzz/corp/sample2.json +++ b/src/fuzz/corp/sample2.json @@ -1,5 +1,5 @@ {"web-app": { - "servlet": [ + "servlet": [ { "servlet-name": "cofaxCDS", "servlet-class": "org.cofax.cds.CDSServlet", @@ -55,7 +55,7 @@ { "servlet-name": "cofaxAdmin", "servlet-class": "org.cofax.cds.AdminServlet"}, - + { "servlet-name": "fileServlet", "servlet-class": "org.cofax.cds.FileServlet"}, @@ -82,7 +82,7 @@ "cofaxAdmin": "/admin/*", "fileServlet": "/static/*", "cofaxTools": "/tools/*"}, - + "taglib": { "taglib-uri": "cofax.tld", "taglib-location": "/WEB-INF/tlds/cofax.tld"}}} diff --git a/src/fuzz/corp/sample3.json b/src/fuzz/corp/sample3.json index 19498e4a3d..bcb69638d0 100644 --- a/src/fuzz/corp/sample3.json +++ b/src/fuzz/corp/sample3.json @@ -23,4 +23,4 @@ "dislikes": ["cookies"] } } -] \ No newline at end of file +] diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp4/udp-header b/src/fuzz/corp/udp-header.pkt4 similarity index 100% rename from src/fuzz/input/fuzz_packets_kea_dhcp4/udp-header rename to src/fuzz/corp/udp-header.pkt4 diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp6/udp-header b/src/fuzz/corp/udp-header.pkt6 similarity index 100% rename from src/fuzz/input/fuzz_packets_kea_dhcp6/udp-header rename to src/fuzz/corp/udp-header.pkt6 diff --git a/src/fuzz/empty_llvm_functions.cc b/src/fuzz/empty_llvm_functions.cc new file mode 100644 index 0000000000..44ca6f1ae0 --- /dev/null +++ b/src/fuzz/empty_llvm_functions.cc @@ -0,0 +1,21 @@ +// Copyright (C) 2026 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// This file should contain only empty LLVMFuzzer.* functions for harnesses contributed externally that did not define +// them to begin with. + +#include +#include + +int +LLVMFuzzerInitialize() { + return 0; +} + +int +LLVMFuzzerTearDown() { + return 0; +} diff --git a/src/fuzz/fuzz_cryptolink.cc b/src/fuzz/fuzz_cryptolink.cc index 700dadf2a6..c357809924 100644 --- a/src/fuzz/fuzz_cryptolink.cc +++ b/src/fuzz/fuzz_cryptolink.cc @@ -25,10 +25,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } FuzzedDataProvider fdp(data, size); - + // Choose which crypto operation to test uint8_t path = fdp.ConsumeIntegralInRange(0, 9); - + // Pick a hash algorithm HashAlgorithm hash_alg = fdp.PickValueInArray({ HashAlgorithm::MD5, @@ -38,7 +38,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { HashAlgorithm::SHA384, HashAlgorithm::SHA512 }); - + try { switch (path) { case 0: { @@ -54,7 +54,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 1: { // Test Hash with multiple updates Hash* hash = CryptoLink::getCryptoLink().createHash(hash_alg); @@ -72,7 +72,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 2: { // Test Hash with OutputBuffer Hash* hash = CryptoLink::getCryptoLink().createHash(hash_alg); @@ -90,7 +90,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 3: { // Test Hash with void* result Hash* hash = CryptoLink::getCryptoLink().createHash(hash_alg); @@ -108,7 +108,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 4: { // Test HMAC creation and signing size_t secret_len = fdp.ConsumeIntegralInRange(1, 256); @@ -116,7 +116,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (secret.empty()) { secret.push_back(0); // Ensure non-empty secret } - + HMAC* hmac = CryptoLink::getCryptoLink().createHMAC( secret.data(), secret.size(), hash_alg ); @@ -130,7 +130,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 5: { // Test HMAC with multiple updates size_t secret_len = fdp.ConsumeIntegralInRange(1, 256); @@ -138,7 +138,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (secret.empty()) { secret.push_back(0); } - + HMAC* hmac = CryptoLink::getCryptoLink().createHMAC( secret.data(), secret.size(), hash_alg ); @@ -156,7 +156,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 6: { // Test HMAC with OutputBuffer size_t secret_len = fdp.ConsumeIntegralInRange(1, 256); @@ -164,7 +164,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (secret.empty()) { secret.push_back(0); } - + HMAC* hmac = CryptoLink::getCryptoLink().createHMAC( secret.data(), secret.size(), hash_alg ); @@ -182,7 +182,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 7: { // Test HMAC verification size_t secret_len = fdp.ConsumeIntegralInRange(1, 256); @@ -190,7 +190,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (secret.empty()) { secret.push_back(0); } - + HMAC* hmac = CryptoLink::getCryptoLink().createHMAC( secret.data(), secret.size(), hash_alg ); @@ -201,10 +201,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (!input_data.empty()) { hmac->update(input_data.data(), input_data.size()); } - + // Generate signature std::vector signature = hmac->sign(hmac->getOutputLength()); - + // Verify with same data (should succeed) HMAC* verify_hmac = CryptoLink::getCryptoLink().createHMAC( secret.data(), secret.size(), hash_alg @@ -220,7 +220,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 8: { // Test HMAC with long secret (should be hashed) size_t secret_len = fdp.ConsumeIntegralInRange(256, 1024); @@ -228,7 +228,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (secret.size() < 64) { secret.resize(64, 0x42); // Pad to ensure long secret } - + HMAC* hmac = CryptoLink::getCryptoLink().createHMAC( secret.data(), secret.size(), hash_alg ); @@ -242,12 +242,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 9: { // Test RNG generation size_t rng_len = fdp.ConsumeIntegralInRange(0, 1024); std::vector random_data = isc::cryptolink::random(rng_len); - + // Test Qid generation uint16_t qid = isc::cryptolink::generateQid(); (void)qid; // Use the variable @@ -259,6 +259,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } catch (const std::exception&) { // Catch any standard library exceptions } - + return 0; } diff --git a/src/fuzz/fuzz_dhcp_parser4.cc b/src/fuzz/fuzz_dhcp_parser4.cc index a56cdc1a12..3557125491 100644 --- a/src/fuzz/fuzz_dhcp_parser4.cc +++ b/src/fuzz/fuzz_dhcp_parser4.cc @@ -177,9 +177,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { // Subnets6ListConfigParser try { ElementPtr elem = fuzz::parseJSON(full_payload); - SrvConfigPtr srv = SrvConfigPtr(new SrvConfig()); + SrvConfigPtr srvconf = SrvConfigPtr(new SrvConfig()); Subnets6ListConfigParser parser(fdp.ConsumeBool()); - parser.parse(srv, elem, fdp.ConsumeBool()); + parser.parse(srvconf, elem, fdp.ConsumeBool()); } catch (const isc::Exception&) { // Known exceptions } @@ -208,9 +208,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { // CompatibilityParser try { ElementPtr elem = fuzz::parseJSON(full_payload); - SrvConfig srv = SrvConfig(); + SrvConfig srvconf = SrvConfig(); CompatibilityParser parser = CompatibilityParser(); - parser.parse(elem, srv); + parser.parse(elem, srvconf); } catch (const isc::Exception&) { // Known exceptions } diff --git a/src/fuzz/fuzz_dhcp_parser6.cc b/src/fuzz/fuzz_dhcp_parser6.cc index 152a990f7f..d75d4c77ba 100644 --- a/src/fuzz/fuzz_dhcp_parser6.cc +++ b/src/fuzz/fuzz_dhcp_parser6.cc @@ -156,9 +156,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Subnets6ListConfigParser try { ElementPtr elem = fuzz::parseJSON(full_payload); - SrvConfigPtr srv = SrvConfigPtr(new SrvConfig()); + SrvConfigPtr srvconf = SrvConfigPtr(new SrvConfig()); Subnets6ListConfigParser parser(fdp.ConsumeBool()); - parser.parse(srv, elem, fdp.ConsumeBool()); + parser.parse(srvconf, elem, fdp.ConsumeBool()); } catch (const isc::Exception&) { // Known exceptions } @@ -187,13 +187,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // CompatibilityParser try { ElementPtr elem = fuzz::parseJSON(full_payload); - SrvConfig srv = SrvConfig(); + SrvConfig srvconf = SrvConfig(); CompatibilityParser parser = CompatibilityParser(); - parser.parse(elem, srv); + parser.parse(elem, srvconf); } catch (const isc::Exception&) { // Known exceptions } return 0; } - diff --git a/src/fuzz/fuzz_dhcp_pkt4.cc b/src/fuzz/fuzz_dhcp_pkt4.cc index 272981d6dc..1a021cf10a 100644 --- a/src/fuzz/fuzz_dhcp_pkt4.cc +++ b/src/fuzz/fuzz_dhcp_pkt4.cc @@ -87,17 +87,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { pkt->pack(); pkt->getName(); pkt->getName(fdp->ConsumeIntegral()); - pkt->getLabel(); + pkt->getLabel(); pkt->getMAC(fdp->ConsumeIntegral()); } catch (...) {} // OptionVendorClass parsing try { - OptionBuffer buf(data, data + size); + OptionBuffer optbuf(data, data + size); OptionVendorClassPtr vendor_class; vendor_class = OptionVendorClassPtr(new OptionVendorClass(Option::V4, - buf.begin(), - buf.end())); + optbuf.begin(), + optbuf.end())); }catch(...){ } @@ -113,24 +113,24 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { pkt->pack(); pkt->getName(); pkt->getName(fdp->ConsumeIntegral()); - pkt->getLabel(); + pkt->getLabel(); pkt->getMAC(fdp->ConsumeIntegral()); } catch (...) {} try { // Protocol parsing - InputBuffer buf(data, size); + InputBuffer inbuf(data, size); Pkt4Ptr pkt = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234)); - decodeEthernetHeader(buf, pkt); - decodeIpUdpHeader(buf, pkt); + decodeEthernetHeader(inbuf, pkt); + decodeIpUdpHeader(inbuf, pkt); calcChecksum(data, size, fdp->ConsumeIntegral()); } catch (...) {} // OptionVendor parsing try{ - OptionBuffer buf(data, data + size); + OptionBuffer outbuf(data, data + size); OptionVendorPtr vendor; - vendor.reset(new OptionVendor(Option::V4, buf.begin() + 2, buf.end())); + vendor.reset(new OptionVendor(Option::V4, outbuf.begin() + 2, outbuf.end())); OutputBuffer output(0); vendor->pack(output); } diff --git a/src/fuzz/fuzz_dhcp_pkt6.cc b/src/fuzz/fuzz_dhcp_pkt6.cc index 0b7418abd1..d30e506f78 100644 --- a/src/fuzz/fuzz_dhcp_pkt6.cc +++ b/src/fuzz/fuzz_dhcp_pkt6.cc @@ -84,11 +84,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { // OptionVendor parsing try { - OptionBuffer buf(data, data + size); + OptionBuffer optbuf(data, data + size); OptionVendorClassPtr vendor_class; vendor_class = OptionVendorClassPtr(new OptionVendorClass(Option::V6, - buf.begin(), - buf.end())); + optbuf.begin(), + optbuf.end())); }catch(...){} try { diff --git a/src/fuzz/fuzz_dhcpsrv.cc b/src/fuzz/fuzz_dhcpsrv.cc index 7740a60a69..285dce201a 100644 --- a/src/fuzz/fuzz_dhcpsrv.cc +++ b/src/fuzz/fuzz_dhcpsrv.cc @@ -205,7 +205,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { hrp.parse(SubnetID(10), elem, fdp.ConsumeBool()); } catch (const isc::Exception&) { // Slient exceptions - } - + } + return 0; } diff --git a/src/fuzz/fuzz_dns.cc b/src/fuzz/fuzz_dns.cc index e484fc97c2..c6bf2e0420 100644 --- a/src/fuzz/fuzz_dns.cc +++ b/src/fuzz/fuzz_dns.cc @@ -44,14 +44,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } FuzzedDataProvider fdp(data, size); - + // Get a choice for which fuzzing path to take uint8_t choice = fdp.ConsumeIntegral(); - + // Reserve some data for different operations std::vector wire_data = fdp.ConsumeBytes(fdp.remaining_bytes() / 2); std::string string_data = fdp.ConsumeRemainingBytesAsString(); - + // Fuzz DNS Name parsing from string if (choice % 8 == 0 && !string_data.empty()) { try { @@ -61,17 +61,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string text = name.toText(); OutputBuffer buffer(0); name.toWire(buffer); - + // Try splitting at different positions if (name.getLabelCount() > 0) { Name stripped = name.split(0); Name reversed = name.reverse(); } - + // Try comparison operations Name root = Name::ROOT_NAME(); name.compare(root); - + } catch (const std::exception&) { // Ignore exceptions from operations } @@ -79,13 +79,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore exceptions from parsing } } - + // Fuzz DNS Name parsing from wire format if (choice % 8 == 1 && !wire_data.empty()) { try { InputBuffer buffer(&wire_data[0], wire_data.size()); Name name(buffer); - + // Try operations on the parsed name try { name.toText(); @@ -98,21 +98,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore exceptions from parsing } } - + // Fuzz DNS Message parsing from wire if (choice % 8 == 2 && !wire_data.empty()) { try { InputBuffer buffer(&wire_data[0], wire_data.size()); Message message(Message::PARSE); message.fromWire(buffer); - + // Try various Message operations try { message.getHeaderFlag(Message::HEADERFLAG_AA); message.getRcode(); message.getQid(); message.getRRCount(Message::SECTION_ANSWER); - + // Try iterating through sections for (int sec = Message::SECTION_QUESTION; sec <= Message::SECTION_ADDITIONAL; @@ -128,7 +128,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore iteration exceptions } } - + // Try rendering back to wire MessageRenderer renderer; try { @@ -136,7 +136,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } catch (const std::exception&) { // Ignore rendering exceptions } - + } catch (const std::exception&) { // Ignore operation exceptions } @@ -144,19 +144,19 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore parsing exceptions } } - + // Fuzz Question parsing if (choice % 8 == 3 && !wire_data.empty()) { try { InputBuffer buffer(&wire_data[0], wire_data.size()); Question question(buffer); - + try { question.toText(); question.getName(); question.getType(); question.getClass(); - + OutputBuffer out_buffer(0); question.toWire(out_buffer); } catch (const std::exception&) { @@ -166,32 +166,32 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore parsing exceptions } } - + // Fuzz RRset operations if (choice % 8 == 4 && !string_data.empty() && !wire_data.empty()) { try { Name name(string_data); - RRsetPtr rrset = RRsetPtr(new RRset(name, RRClass::IN(), + RRsetPtr rrset = RRsetPtr(new RRset(name, RRClass::IN(), RRType::A(), RRTTL(3600))); - + // Try parsing RDATA from wire try { InputBuffer buffer(&wire_data[0], wire_data.size()); if (wire_data.size() >= 4) { - rdata::ConstRdataPtr rdata = - rdata::createRdata(RRType::A(), RRClass::IN(), + rdata::ConstRdataPtr rdata = + rdata::createRdata(RRType::A(), RRClass::IN(), buffer, wire_data.size()); rrset->addRdata(rdata); } } catch (const std::exception&) { // Ignore RDATA parsing exceptions } - + // Try RRset operations try { rrset->toText(); rrset->getRdataCount(); - + OutputBuffer out_buffer(0); rrset->toWire(out_buffer); } catch (const std::exception&) { @@ -201,34 +201,34 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore exceptions } } - + // Fuzz TSIG operations if (choice % 8 == 5 && !string_data.empty() && wire_data.size() >= 16) { try { // Try creating a TSIG key TSIGKey key(string_data + ":secret"); - + // Try creating TSIG RDATA and then a TSIG record try { InputBuffer buffer(&wire_data[0], wire_data.size()); // Try to parse TSIG RDATA - rdata::ConstRdataPtr rdata = - rdata::createRdata(RRType::TSIG(), RRClass::ANY(), + rdata::ConstRdataPtr rdata = + rdata::createRdata(RRType::TSIG(), RRClass::ANY(), buffer, wire_data.size()); - const rdata::any::TSIG& tsig_rdata = + const rdata::any::TSIG& tsig_rdata = dynamic_cast(*rdata); - + // Create a TSIGRecord Name key_name(string_data); TSIGRecord tsig(key_name, tsig_rdata); tsig.toText(); - + OutputBuffer out_buffer(0); tsig.toWire(out_buffer); } catch (const std::exception&) { // Ignore TSIG parsing exceptions } - + // Try TSIG context operations (sign operation is public) try { TSIGContext ctx(key); @@ -243,24 +243,24 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore key creation exceptions } } - + // Fuzz MasterLexer with string input if (choice % 8 == 6 && !string_data.empty()) { try { std::istringstream iss(string_data); MasterLexer lexer; lexer.pushSource(iss); - + // Try tokenizing (loop until we hit EOF token) for (int i = 0; i < 100; ++i) { try { const MasterToken& token = lexer.getNextToken(); - + // Stop if we hit EOF if (token.getType() == MasterToken::END_OF_FILE) { break; } - + // Access token properties based on type if (token.getType() == MasterToken::STRING || token.getType() == MasterToken::QSTRING) { @@ -280,7 +280,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore lexer exceptions } } - + // Fuzz Message rendering operations if (choice % 8 == 7 && !string_data.empty()) { try { @@ -288,25 +288,25 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { message.setQid(fdp.ConsumeIntegral()); message.setOpcode(Opcode::QUERY()); message.setRcode(Rcode::NOERROR()); - + // Try setting various flags - message.setHeaderFlag(Message::HEADERFLAG_AA, + message.setHeaderFlag(Message::HEADERFLAG_AA, fdp.ConsumeBool()); - message.setHeaderFlag(Message::HEADERFLAG_RD, + message.setHeaderFlag(Message::HEADERFLAG_RD, fdp.ConsumeBool()); - message.setHeaderFlag(Message::HEADERFLAG_RA, + message.setHeaderFlag(Message::HEADERFLAG_RA, fdp.ConsumeBool()); - + // Try adding a question try { Name qname(string_data); - QuestionPtr question(new Question(qname, RRClass::IN(), + QuestionPtr question(new Question(qname, RRClass::IN(), RRType::A())); message.addQuestion(question); } catch (const std::exception&) { // Ignore question addition exceptions } - + // Try rendering try { MessageRenderer renderer; @@ -318,6 +318,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Ignore message creation exceptions } } - + return 0; } diff --git a/src/fuzz/fuzz_encode.cc b/src/fuzz/fuzz_encode.cc index 99446d9772..52291b3ad2 100644 --- a/src/fuzz/fuzz_encode.cc +++ b/src/fuzz/fuzz_encode.cc @@ -22,14 +22,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } FuzzedDataProvider fdp(data, size); - + // Choose which encoding/decoding path to test uint8_t path = fdp.ConsumeIntegralInRange(0, 11); - + std::vector binary_data; std::string encoded_str; std::vector decoded_output; - + switch (path) { case 0: { // Test Base64 encoding from binary data @@ -44,7 +44,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 1: { // Test Base64 decoding from string try { @@ -55,7 +55,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 2: { // Test Base32Hex encoding from binary data try { @@ -69,7 +69,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 3: { // Test Base32Hex decoding from string try { @@ -80,7 +80,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 4: { // Test Base16 (hex) encoding from binary data try { @@ -94,7 +94,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 5: { // Test Base16 (hex) decoding from string try { @@ -105,7 +105,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 6: { // Test Base64 with various padding scenarios try { @@ -119,7 +119,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 7: { // Test Base32Hex with various padding scenarios try { @@ -134,7 +134,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 8: { // Test mixed case Base64 (should be case-sensitive) try { @@ -151,7 +151,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 9: { // Test mixed case Base32Hex (case-insensitive) try { @@ -168,7 +168,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 10: { // Test Base16 with mixed case (case-insensitive) try { @@ -185,7 +185,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } break; } - + case 11: { // Test encoding/decoding with whitespace injection try { @@ -197,7 +197,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { char ws = fdp.PickValueInArray({' ', '\t', '\n', '\r'}); test_str.insert(pos, 1, ws); } - + // Try decoding with all encoders try { decodeBase64(test_str, decoded_output); } catch (...) {} try { decodeBase32Hex(test_str, decoded_output); } catch (...) {} @@ -208,6 +208,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { break; } } - + return 0; } diff --git a/src/fuzz/fuzz_hook_tsig.cc b/src/fuzz/fuzz_hook_tsig.cc index 43479e260e..069fbe34d3 100644 --- a/src/fuzz/fuzz_hook_tsig.cc +++ b/src/fuzz/fuzz_hook_tsig.cc @@ -34,7 +34,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::string tsig_rdata_txt = fdp.ConsumeRandomLengthString(1024); std::string owner_txt = fdp.ConsumeRandomLengthString(128); const uint16_t qid = fdp.ConsumeIntegral(); - const bool do_chunked = fdp.ConsumeBool(); // Target correct key sign and verify try { diff --git a/src/fuzz/fuzz_ioaddress.cc b/src/fuzz/fuzz_ioaddress.cc index 4cc4bece22..1a1a11eb5c 100644 --- a/src/fuzz/fuzz_ioaddress.cc +++ b/src/fuzz/fuzz_ioaddress.cc @@ -4,6 +4,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //////////////////////////////////////////////////////////////////////////////// + +#include + #include #include #include diff --git a/src/fuzz/fuzz_util.cc b/src/fuzz/fuzz_util.cc index 50347add7f..283ab56adb 100644 --- a/src/fuzz/fuzz_util.cc +++ b/src/fuzz/fuzz_util.cc @@ -99,7 +99,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Target CSVRow try { CSVRow row(payload, delim[0]); - for (int i = 0; i < row.getValuesCount(); i++) { + for (size_t i = 0; i < row.getValuesCount(); i++) { row.readAt(i); row.readAtEscaped(i); } @@ -153,4 +153,3 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } - diff --git a/src/fuzz/helper_func.cc b/src/fuzz/helper_func.cc index 7534230d5f..2472f3f7aa 100644 --- a/src/fuzz/helper_func.cc +++ b/src/fuzz/helper_func.cc @@ -4,6 +4,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //////////////////////////////////////////////////////////////////////////////// + +#include + #include "helper_func.h" #include diff --git a/src/fuzz/input/fuzz_config_kea_dhcp4/doc-examples b/src/fuzz/input/fuzz_config_kea_dhcp4/doc-examples deleted file mode 120000 index 6409262312..0000000000 --- a/src/fuzz/input/fuzz_config_kea_dhcp4/doc-examples +++ /dev/null @@ -1 +0,0 @@ -../../../../doc/examples/kea4 \ No newline at end of file diff --git a/src/fuzz/input/fuzz_config_kea_dhcp6/doc-examples b/src/fuzz/input/fuzz_config_kea_dhcp6/doc-examples deleted file mode 120000 index 76ea62b711..0000000000 --- a/src/fuzz/input/fuzz_config_kea_dhcp6/doc-examples +++ /dev/null @@ -1 +0,0 @@ -../../../../doc/examples/kea6 \ No newline at end of file diff --git a/src/fuzz/input/fuzz_config_kea_dhcp6/empty b/src/fuzz/input/fuzz_config_kea_dhcp6/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/fuzz/input/fuzz_config_kea_dhcp6/one-byte b/src/fuzz/input/fuzz_config_kea_dhcp6/one-byte deleted file mode 100644 index 47d26df80d..0000000000 --- a/src/fuzz/input/fuzz_config_kea_dhcp6/one-byte +++ /dev/null @@ -1 +0,0 @@ -0a \ No newline at end of file diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/config-get b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/config-get deleted file mode 100644 index 7ce1bfffff..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/config-get +++ /dev/null @@ -1,3 +0,0 @@ -{ - "command": "config-get" -} diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/config-get-with-service b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/config-get-with-service deleted file mode 100644 index 11ed27a1c2..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/config-get-with-service +++ /dev/null @@ -1,4 +0,0 @@ -{ - "command": "config-get", - "service": [ "dhcp4" ] -} diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/empty b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/empty-json-map b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/empty-json-map deleted file mode 100644 index 0967ef424b..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/empty-json-map +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/one-byte b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/one-byte deleted file mode 100644 index 47d26df80d..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/one-byte +++ /dev/null @@ -1 +0,0 @@ -0a \ No newline at end of file diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/one-entry-json-map b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/one-entry-json-map deleted file mode 100644 index 8d6b85c7b3..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp4/one-entry-json-map +++ /dev/null @@ -1,3 +0,0 @@ -{ - "a": 1 -} diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/config-get b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/config-get deleted file mode 100644 index 7ce1bfffff..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/config-get +++ /dev/null @@ -1,3 +0,0 @@ -{ - "command": "config-get" -} diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/config-get-with-service b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/config-get-with-service deleted file mode 100644 index df926792e3..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/config-get-with-service +++ /dev/null @@ -1,4 +0,0 @@ -{ - "command": "config-get", - "service": [ "dhcp6" ] -} diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/empty b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/empty-json-map b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/empty-json-map deleted file mode 100644 index 0967ef424b..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/empty-json-map +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/one-byte b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/one-byte deleted file mode 100644 index 47d26df80d..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/one-byte +++ /dev/null @@ -1 +0,0 @@ -0a \ No newline at end of file diff --git a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/one-entry-json-map b/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/one-entry-json-map deleted file mode 100644 index 8d6b85c7b3..0000000000 --- a/src/fuzz/input/fuzz_http_endpoint_kea_dhcp6/one-entry-json-map +++ /dev/null @@ -1,3 +0,0 @@ -{ - "a": 1 -} diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp4/empty b/src/fuzz/input/fuzz_packets_kea_dhcp4/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp4/one-byte b/src/fuzz/input/fuzz_packets_kea_dhcp4/one-byte deleted file mode 100644 index 47d26df80d..0000000000 --- a/src/fuzz/input/fuzz_packets_kea_dhcp4/one-byte +++ /dev/null @@ -1 +0,0 @@ -0a \ No newline at end of file diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp6/empty b/src/fuzz/input/fuzz_packets_kea_dhcp6/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/fuzz/input/fuzz_packets_kea_dhcp6/one-byte b/src/fuzz/input/fuzz_packets_kea_dhcp6/one-byte deleted file mode 100644 index 47d26df80d..0000000000 --- a/src/fuzz/input/fuzz_packets_kea_dhcp6/one-byte +++ /dev/null @@ -1 +0,0 @@ -0a \ No newline at end of file diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/config-get b/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/config-get deleted file mode 100644 index 7ce1bfffff..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/config-get +++ /dev/null @@ -1,3 +0,0 @@ -{ - "command": "config-get" -} diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/config-get-with-service b/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/config-get-with-service deleted file mode 100644 index 11ed27a1c2..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/config-get-with-service +++ /dev/null @@ -1,4 +0,0 @@ -{ - "command": "config-get", - "service": [ "dhcp4" ] -} diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/empty b/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/empty-json-map b/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/empty-json-map deleted file mode 100644 index 0967ef424b..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/empty-json-map +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/one-byte b/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/one-byte deleted file mode 100644 index 47d26df80d..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/one-byte +++ /dev/null @@ -1 +0,0 @@ -0a \ No newline at end of file diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/one-entry-json-map b/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/one-entry-json-map deleted file mode 100644 index 8d6b85c7b3..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp4/one-entry-json-map +++ /dev/null @@ -1,3 +0,0 @@ -{ - "a": 1 -} diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/config-get b/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/config-get deleted file mode 100644 index 7ce1bfffff..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/config-get +++ /dev/null @@ -1,3 +0,0 @@ -{ - "command": "config-get" -} diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/config-get-with-service b/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/config-get-with-service deleted file mode 100644 index df926792e3..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/config-get-with-service +++ /dev/null @@ -1,4 +0,0 @@ -{ - "command": "config-get", - "service": [ "dhcp6" ] -} diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/empty b/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/empty-json-map b/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/empty-json-map deleted file mode 100644 index 0967ef424b..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/empty-json-map +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/one-byte b/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/one-byte deleted file mode 100644 index 47d26df80d..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/one-byte +++ /dev/null @@ -1 +0,0 @@ -0a \ No newline at end of file diff --git a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/one-entry-json-map b/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/one-entry-json-map deleted file mode 100644 index 8d6b85c7b3..0000000000 --- a/src/fuzz/input/fuzz_unix_socket_kea_dhcp6/one-entry-json-map +++ /dev/null @@ -1,3 +0,0 @@ -{ - "a": 1 -} diff --git a/src/fuzz/install-input.sh.in b/src/fuzz/install-input.sh.in deleted file mode 100755 index 0b7b840bdc..0000000000 --- a/src/fuzz/install-input.sh.in +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh - -set -eu - -# Destdir is set everytime the installation happens through meson or ninja even when --destdir is not passed. -# Set target path to prefix in case someone wants to run this script directly. -target_path='@PREFIX@' -if test -n "${MESON_INSTALL_DESTDIR_PREFIX+x}"; then - target_path="${MESON_INSTALL_DESTDIR_PREFIX}" -fi - -mkdir -p "${target_path}/share/kea/fuzz" -cp -r '@current_build_dir@/input'/* "${target_path}/share/kea/fuzz" diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build index bc7650faaf..99ee7f1ad0 100644 --- a/src/fuzz/meson.build +++ b/src/fuzz/meson.build @@ -5,41 +5,23 @@ endif current_build_dir = meson.current_build_dir() current_source_dir = meson.current_source_dir() -foreach i : [ - 'fuzz_config_kea_dhcp4', - 'fuzz_config_kea_dhcp6', - 'fuzz_http_endpoint_kea_dhcp4', - 'fuzz_http_endpoint_kea_dhcp6', - 'fuzz_packets_kea_dhcp4', - 'fuzz_packets_kea_dhcp6', - 'fuzz_unix_socket_kea_dhcp4', - 'fuzz_unix_socket_kea_dhcp6', - 'fuzz_config_kea_dhcp4/doc-examples', - 'fuzz_config_kea_dhcp6/doc-examples', -] - command = run_command(GRABBER, f'input/@i@', '*', check: true) - foreach j : command.stdout().strip().split('\n') - # configure_file doesn't work with path segments in the output, so let - # us simulate it with commands. - run_command( - ['mkdir', '-p', f'@TOP_BUILD_DIR@/fuzz/input/@i@'], - check: true, - ) - run_command( - ['cp', f'input/@i@/@j@', f'@TOP_BUILD_DIR@/fuzz/input/@i@/@j@'], - check: true, - ) - endforeach - -endforeach - -fuzz_sources = ['fuzz.cc', 'fuzz.h', 'main.cc'] +fuzz_sources = ['fuzz.cc', 'fuzz.h'] cpp_flags = [ f'-DKEA_LFC_INSTALLATION="@KEA_LFC_INSTALLED@"', f'-DKEA_LFC_SOURCES="@KEA_LFC_BUILT@"', ] -includes = [include_directories('.')] + INCLUDES +# The include paths are a bit invasive, but if we wanted to only have "../hooks" we would need to +# tweak the include paths in the hooks themselves either to be referenced from "src" or +# "src/hooks" or to have quotes instead of angled brackets and that is more work. +includes = [ + include_directories('.'), + include_directories('../hooks'), + include_directories('../hooks/d2/gss_tsig'), + include_directories('../hooks/dhcp/mysql'), + include_directories('../hooks/dhcp/pgsql'), + include_directories('../hooks/dhcp/user_chk'), +] + INCLUDES fuzz_lib = static_library( 'fuzz_lib', @@ -50,7 +32,7 @@ fuzz_lib = static_library( link_with: LIBS_BUILT_SO_FAR, ) -FUZZER_EXECUTABLES = [] +FUZZING_HARNESSES = [] foreach i : [ 'fuzz_config_kea_dhcp4', @@ -58,7 +40,7 @@ foreach i : [ 'fuzz_packets_kea_dhcp4', 'fuzz_unix_socket_kea_dhcp4', ] - FUZZER_EXECUTABLES += executable( + FUZZING_HARNESSES += static_library( i, f'@i@.cc', fuzz_sources, @@ -66,19 +48,17 @@ foreach i : [ dependencies: [CRYPTO_DEP, GTEST_DEP], include_directories: includes, link_with: [dhcp4_lib, kea_testutils_lib, fuzz_lib] + LIBS_BUILT_SO_FAR, - install: true, - install_dir: SBINDIR, - install_rpath: INSTALL_RPATH, build_rpath: BUILD_RPATH, ) endforeach + foreach i : [ 'fuzz_config_kea_dhcp6', 'fuzz_http_endpoint_kea_dhcp6', 'fuzz_packets_kea_dhcp6', 'fuzz_unix_socket_kea_dhcp6', ] - FUZZER_EXECUTABLES += executable( + FUZZING_HARNESSES += static_library( i, f'@i@.cc', fuzz_sources, @@ -86,11 +66,82 @@ foreach i : [ dependencies: [CRYPTO_DEP, GTEST_DEP], include_directories: includes, link_with: [dhcp6_lib, kea_testutils_lib, fuzz_lib] + LIBS_BUILT_SO_FAR, - install: true, - install_dir: SBINDIR, - install_rpath: INSTALL_RPATH, build_rpath: BUILD_RPATH, ) endforeach +# From external contribution. +foreach i : [ + 'fuzz_agent', + 'fuzz_cc', + 'fuzz_crypto', + 'fuzz_cryptolink', + 'fuzz_d2', + 'fuzz_dhcp_parser4', + 'fuzz_dhcp_parser6', + 'fuzz_dhcp_pkt4', + 'fuzz_dhcp_pkt6', + 'fuzz_dhcp_pkt_process4', + 'fuzz_dhcp_pkt_process6', + 'fuzz_dhcpsrv', + 'fuzz_dhcpsrv_csv_lease', + 'fuzz_dns', + 'fuzz_encode', + 'fuzz_eval4', + 'fuzz_eval6', + 'fuzz_hook_ddns_tuning4', + 'fuzz_hook_ddns_tuning6', + 'fuzz_hook_flex_id4', + 'fuzz_hook_flex_id6', + 'fuzz_hook_lease_query4', + 'fuzz_hook_lease_query6', + 'fuzz_hook_radius4', + 'fuzz_hook_radius6', + 'fuzz_hook_run_script4', + 'fuzz_hook_run_script6', + 'fuzz_hook_tsig', + 'fuzz_hook_user_chk4', + 'fuzz_hook_user_chk6', + 'fuzz_http', + 'fuzz_ioaddress', + 'fuzz_mysql4', + 'fuzz_mysql6', + 'fuzz_pgsql4', + 'fuzz_pgsql6', + 'fuzz_util', +] + FUZZING_HARNESSES += static_library( + i, + f'@i@.cc', + 'empty_llvm_functions.cc', + 'helper_func.cc', + 'mysqlmock.cc', + 'pgmock.cc', + fuzz_sources, + cpp_args: cpp_flags, + dependencies: [MYSQL_DEP, POSTGRESQL_DEP, CRYPTO_DEP, GTEST_DEP], + include_directories: includes, + link_with: [ + agent_lib, + d2_lib, + ddns_gss_tsig_lib, + dhcp_lease_query_lib, + dhcp_flex_id_lib, + dhcp_ddns_tuning_lib, + dhcp_lease_cmds_lib, + dhcp_mysql_lib, + dhcp_pgsql_lib, + dhcp_radius_lib, + dhcp_run_script_lib, + dhcp_user_chk_lib, + dhcp4_lib, + dhcp6_lib, + kea_testutils_lib, + fuzz_lib, + ] + LIBS_BUILT_SO_FAR, + build_rpath: BUILD_RPATH, + ) +endforeach + +subdir('corp') subdir('tests') diff --git a/src/fuzz/mysqlmock.cc b/src/fuzz/mysqlmock.cc index 600ab8450e..b0d2b93782 100644 --- a/src/fuzz/mysqlmock.cc +++ b/src/fuzz/mysqlmock.cc @@ -4,9 +4,12 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //////////////////////////////////////////////////////////////////////////////// + +#include + #include -#include +#include #include #include @@ -72,13 +75,6 @@ static bool is_like(const std::string& hay, const char* needle) { return h.find(n) != std::string::npos; } -static MYSQL_STMT* make_stmt() { - auto s = new StmtState(); - s->mysql = reinterpret_cast(0x1); - g_live_stmts.push_back(s); - return reinterpret_cast(s); -} - static StmtState* SS(MYSQL_STMT* st) { if (!st) { return nullptr; @@ -211,7 +207,7 @@ static void fill_fuzz_rows(StmtState* s, unsigned int ncols) { } extern "C" { - int mysql_server_init(int argc, char **argv, char **groups) { + int mysql_server_init(int /* argc */, char ** /* argv */, char ** /* groups */) { return 0; } diff --git a/src/fuzz/pgmock.cc b/src/fuzz/pgmock.cc index b71f021dee..d885e5a8ed 100644 --- a/src/fuzz/pgmock.cc +++ b/src/fuzz/pgmock.cc @@ -4,6 +4,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. //////////////////////////////////////////////////////////////////////////////// + +#include + #include #include @@ -133,14 +136,14 @@ extern "C" { return const_cast(""); } - PGresult* PQexec(PGconn* , const char* query) { + PGresult* PQexec(PGconn* , const char* /* query */) { if (g_fdp->ConsumeBool()) { return make_version_result(); } return make_fuzz_result(); } - PGresult* PQexecParams(PGconn*, const char* cmd, int, const void*, + PGresult* PQexecParams(PGconn*, const char* /* cmd */, int, const void*, const char* const*, const int*, const int*, int) { if (g_fdp->ConsumeBool()) { return make_version_result(); @@ -152,7 +155,7 @@ extern "C" { return make_command_ok_result(); } - PGresult* PQexecPrepared(PGconn*, const char* name, int, const char* const*, + PGresult* PQexecPrepared(PGconn*, const char* /* name */, int, const char* const*, const int*, const int*, int) { if (g_fdp->ConsumeBool()) { return make_version_result(); diff --git a/src/fuzz/main.cc b/src/fuzz/tests/main.cc similarity index 90% rename from src/fuzz/main.cc rename to src/fuzz/tests/main.cc index 707bfa575b..b750f03e08 100644 --- a/src/fuzz/main.cc +++ b/src/fuzz/tests/main.cc @@ -4,6 +4,9 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +// This file should contain all the symbols which are added by OSS-Fuzz like the main function and the LLVMFuzzer.* +// functions. + #include #include @@ -36,10 +39,10 @@ main(int, char* argv[]) { // Determine some paths. Path const this_binary(argv[0]); - string ancestor_path(this_binary.parentPath()); + string const ancestor_path(this_binary.parentPath()); string const filename(this_binary.filename()); stringstream ss; - ss << ancestor_path << "/input/" << filename; + ss << ancestor_path << "/../corp"; Path const p(ss.str()); // Print start header. @@ -53,6 +56,8 @@ main(int, char* argv[]) { string directory(p.str()); if (exists(directory)) { // Recursively take all regular files as input. + // This means each fuzzing harness runs against each input even if the input is meant for a different fuzzing + // harness. A bit chaotic, but let us call it limited fuzzing. list files; struct dirent *dp; diff --git a/src/fuzz/tests/meson.build b/src/fuzz/tests/meson.build index 4f5e1d41bc..bf48ebaac3 100644 --- a/src/fuzz/tests/meson.build +++ b/src/fuzz/tests/meson.build @@ -1,7 +1,15 @@ -foreach f : FUZZER_EXECUTABLES +foreach f : FUZZING_HARNESSES + n = f.name() + t = executable( + f'test_@n@', + 'main.cc', + include_directories: [include_directories('..')] + INCLUDES, + link_with: [f], + build_rpath: BUILD_RPATH, + ) test( - f.name(), - f, + t.name(), + t, is_parallel: false, priority: -1, )