diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index 2709624ce..2ab176666 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -13,13 +13,30 @@ # ar ruv libFuzzer.a Fuzzer*.o if (ENABLE_FUZZING) - add_executable(driver driver.cc $ $) - target_link_libraries(driver Fuzzer osrm) - add_custom_target(fuzz - DEPENDS driver - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E make_directory corpus - COMMAND driver -jobs=4 -workers=4 -max_len=4096 corpus - COMMENT "Fuzzing libosrm" VERBATIM) + macro(add_fuzz_target binary) + add_executable(${binary} ${binary}.cc $ $) + target_link_libraries(${binary} Fuzzer osrm) + target_include_directories(${binary} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + + add_custom_target(fuzz-${binary} + DEPENDS ${binary} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory "corpus/${binary}" + COMMAND ${binary} -jobs=1 -max_len=4096 "corpus/${binary}" + COMMENT "Fuzzing ${binary}" VERBATIM) + endmacro () + + set(targets + "match_parameters" + "nearest_parameters" + "route_parameters" + "table_parameters" + "tile_parameters" + "trip_parameters") + + foreach (target ${targets}) + add_fuzz_target(${target}) + endforeach () + endif () diff --git a/fuzz/driver.cc b/fuzz/driver.cc deleted file mode 100644 index 5910ef488..000000000 --- a/fuzz/driver.cc +++ /dev/null @@ -1,32 +0,0 @@ -#include "server/api/parameters_parser.hpp" - -#include "engine/api/base_parameters.hpp" -#include "engine/api/match_parameters.hpp" -#include "engine/api/nearest_parameters.hpp" -#include "engine/api/route_parameters.hpp" -#include "engine/api/table_parameters.hpp" -#include "engine/api/tile_parameters.hpp" -#include "engine/api/trip_parameters.hpp" - -#include -#include - -/* - * First pass at fuzzing the server, without any libosrm setup. - * Later we want keep state across fuzz testing invocations via: - * - * struct State { State() { setup_osrm(); } }; - * static State state; - */ - -extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) -{ - std::string in(reinterpret_cast(data), size); - - auto first = begin(in); - const auto last = end(in); - - (void)osrm::server::api::parseParameters(first, last); - - return 0; /* Always return zero, sanitizers hard-abort */ -} diff --git a/fuzz/match_parameters.cc b/fuzz/match_parameters.cc new file mode 100644 index 000000000..19da8b145 --- /dev/null +++ b/fuzz/match_parameters.cc @@ -0,0 +1,23 @@ +#include "engine/api/match_parameters.hpp" +#include "server/api/parameters_parser.hpp" + +#include "util.hpp" + +#include +#include + +using osrm::server::api::parseParameters; +using osrm::engine::api::MatchParameters; + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) +{ + std::string in(reinterpret_cast(data), size); + + auto first = begin(in); + const auto last = end(in); + + const auto param = parseParameters(first, last); + escape(¶m); + + return 0; +} diff --git a/fuzz/nearest_parameters.cc b/fuzz/nearest_parameters.cc new file mode 100644 index 000000000..71c95bfed --- /dev/null +++ b/fuzz/nearest_parameters.cc @@ -0,0 +1,23 @@ +#include "engine/api/nearest_parameters.hpp" +#include "server/api/parameters_parser.hpp" + +#include "util.hpp" + +#include +#include + +using osrm::server::api::parseParameters; +using osrm::engine::api::NearestParameters; + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) +{ + std::string in(reinterpret_cast(data), size); + + auto first = begin(in); + const auto last = end(in); + + const auto param = parseParameters(first, last); + escape(¶m); + + return 0; +} diff --git a/fuzz/route_parameters.cc b/fuzz/route_parameters.cc new file mode 100644 index 000000000..b3a80b05b --- /dev/null +++ b/fuzz/route_parameters.cc @@ -0,0 +1,23 @@ +#include "engine/api/route_parameters.hpp" +#include "server/api/parameters_parser.hpp" + +#include "util.hpp" + +#include +#include + +using osrm::server::api::parseParameters; +using osrm::engine::api::RouteParameters; + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) +{ + std::string in(reinterpret_cast(data), size); + + auto first = begin(in); + const auto last = end(in); + + const auto param = parseParameters(first, last); + escape(¶m); + + return 0; +} diff --git a/fuzz/table_parameters.cc b/fuzz/table_parameters.cc new file mode 100644 index 000000000..851f7a47d --- /dev/null +++ b/fuzz/table_parameters.cc @@ -0,0 +1,23 @@ +#include "engine/api/table_parameters.hpp" +#include "server/api/parameters_parser.hpp" + +#include "util.hpp" + +#include +#include + +using osrm::server::api::parseParameters; +using osrm::engine::api::TableParameters; + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) +{ + std::string in(reinterpret_cast(data), size); + + auto first = begin(in); + const auto last = end(in); + + const auto param = parseParameters(first, last); + escape(¶m); + + return 0; +} diff --git a/fuzz/tile_parameters.cc b/fuzz/tile_parameters.cc new file mode 100644 index 000000000..405544e5f --- /dev/null +++ b/fuzz/tile_parameters.cc @@ -0,0 +1,23 @@ +#include "engine/api/tile_parameters.hpp" +#include "server/api/parameters_parser.hpp" + +#include "util.hpp" + +#include +#include + +using osrm::server::api::parseParameters; +using osrm::engine::api::TileParameters; + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) +{ + std::string in(reinterpret_cast(data), size); + + auto first = begin(in); + const auto last = end(in); + + const auto param = parseParameters(first, last); + escape(¶m); + + return 0; +} diff --git a/fuzz/trip_parameters.cc b/fuzz/trip_parameters.cc new file mode 100644 index 000000000..501d65d0a --- /dev/null +++ b/fuzz/trip_parameters.cc @@ -0,0 +1,23 @@ +#include "engine/api/trip_parameters.hpp" +#include "server/api/parameters_parser.hpp" + +#include "util.hpp" + +#include +#include + +using osrm::server::api::parseParameters; +using osrm::engine::api::TripParameters; + +extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size) +{ + std::string in(reinterpret_cast(data), size); + + auto first = begin(in); + const auto last = end(in); + + const auto param = parseParameters(first, last); + escape(¶m); + + return 0; +} diff --git a/fuzz/util.hpp b/fuzz/util.hpp new file mode 100644 index 000000000..490957a39 --- /dev/null +++ b/fuzz/util.hpp @@ -0,0 +1,16 @@ +#ifndef OSRM_FUZZ_UTIL_HPP +#define OSRM_FUZZ_UTIL_HPP + +#include + +// Fakes observable side effects the compiler can not optimize away +template inline void escape(T p) +{ + static_assert(std::is_pointer::value, ""); + asm volatile("" : : "g"((void *)p) : "memory"); +} + +// Possibly reads and writes all the memory in your system +inline void clobber() { asm volatile("" : : : "memory"); } + +#endif