mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
test: Add fuzz tests to the coverage run.
So we don't need to write so many edge case tests ourselves for things like parsers, which really don't need those manual tests, as long as we can check for some properties like "can output the parsed data and it'll be the same as the input".
This commit is contained in:
parent
df76f5cf47
commit
50f1b30fa9
|
@ -160,21 +160,7 @@ if(BOOTSTRAP_DAEMON AND WIN32)
|
||||||
set(BOOTSTRAP_DAEMON OFF)
|
set(BOOTSTRAP_DAEMON OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Enabling this breaks all other tests and no network connections will be possible
|
|
||||||
option(BUILD_FUZZ_TESTS "Build fuzzing harnesses" OFF)
|
option(BUILD_FUZZ_TESTS "Build fuzzing harnesses" OFF)
|
||||||
if(BUILD_FUZZ_TESTS)
|
|
||||||
message(STATUS "Building in fuzz testing mode, no network connection will be possible")
|
|
||||||
# Disable everything we can
|
|
||||||
set(AUTOTEST OFF)
|
|
||||||
set(BUILD_MISC_TESTS OFF)
|
|
||||||
set(BUILD_FUN_UTILS OFF)
|
|
||||||
set(ENABLE_SHARED OFF)
|
|
||||||
set(MUST_BUILD_TOXAV OFF)
|
|
||||||
set(BUILD_TOXAV OFF)
|
|
||||||
set(BOOTSTRAP_DAEMON OFF)
|
|
||||||
set(DHT_BOOTSTRAP OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
option(MSVC_STATIC_SODIUM "Whether to link libsodium statically for MSVC" OFF)
|
option(MSVC_STATIC_SODIUM "Whether to link libsodium statically for MSVC" OFF)
|
||||||
|
@ -448,20 +434,33 @@ endif()
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# Create combined library from all the sources.
|
# Create combined library from all the sources.
|
||||||
add_module(toxcore ${toxcore_SOURCES})
|
if(ENABLE_SHARED)
|
||||||
|
add_library(toxcore_shared SHARED ${toxcore_SOURCES})
|
||||||
|
set_target_properties(toxcore_shared PROPERTIES OUTPUT_NAME toxcore)
|
||||||
|
target_link_libraries(toxcore_shared PRIVATE ${toxcore_LINK_LIBRARIES})
|
||||||
|
target_link_directories(toxcore_shared PUBLIC ${toxcore_LINK_DIRECTORIES})
|
||||||
|
target_include_directories(toxcore_shared SYSTEM PRIVATE ${toxcore_INCLUDE_DIRECTORIES})
|
||||||
|
target_compile_options(toxcore_shared PRIVATE ${toxcore_COMPILE_OPTIONS})
|
||||||
|
endif()
|
||||||
|
|
||||||
# Link it to all dependencies.
|
if(ENABLE_STATIC)
|
||||||
if(TARGET toxcore_static)
|
add_library(toxcore_static STATIC ${toxcore_SOURCES})
|
||||||
|
if(NOT MSVC)
|
||||||
|
set_target_properties(toxcore_static PROPERTIES OUTPUT_NAME toxcore)
|
||||||
|
endif()
|
||||||
target_link_libraries(toxcore_static PRIVATE ${toxcore_LINK_LIBRARIES})
|
target_link_libraries(toxcore_static PRIVATE ${toxcore_LINK_LIBRARIES})
|
||||||
target_link_directories(toxcore_static PUBLIC ${toxcore_LINK_DIRECTORIES})
|
target_link_directories(toxcore_static PUBLIC ${toxcore_LINK_DIRECTORIES})
|
||||||
target_include_directories(toxcore_static SYSTEM PRIVATE ${toxcore_INCLUDE_DIRECTORIES})
|
target_include_directories(toxcore_static SYSTEM PRIVATE ${toxcore_INCLUDE_DIRECTORIES})
|
||||||
target_compile_options(toxcore_static PRIVATE ${toxcore_COMPILE_OPTIONS})
|
target_compile_options(toxcore_static PRIVATE ${toxcore_COMPILE_OPTIONS})
|
||||||
endif()
|
endif()
|
||||||
if(TARGET toxcore_shared)
|
|
||||||
target_link_libraries(toxcore_shared PRIVATE ${toxcore_LINK_LIBRARIES})
|
if(BUILD_FUZZ_TESTS)
|
||||||
target_link_directories(toxcore_shared PUBLIC ${toxcore_LINK_DIRECTORIES})
|
add_library(toxcore_fuzz STATIC ${toxcore_SOURCES})
|
||||||
target_include_directories(toxcore_shared SYSTEM PRIVATE ${toxcore_INCLUDE_DIRECTORIES})
|
target_link_libraries(toxcore_fuzz PRIVATE ${toxcore_LINK_LIBRARIES})
|
||||||
target_compile_options(toxcore_shared PRIVATE ${toxcore_COMPILE_OPTIONS})
|
target_link_directories(toxcore_fuzz PUBLIC ${toxcore_LINK_DIRECTORIES})
|
||||||
|
target_include_directories(toxcore_fuzz SYSTEM PRIVATE ${toxcore_INCLUDE_DIRECTORIES})
|
||||||
|
target_compile_options(toxcore_fuzz PRIVATE ${toxcore_COMPILE_OPTIONS})
|
||||||
|
target_compile_definitions(toxcore_fuzz PUBLIC "FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Make version script (on systems that support it) to limit symbol visibility.
|
# Make version script (on systems that support it) to limit symbol visibility.
|
||||||
|
|
|
@ -19,19 +19,6 @@ if(FULLY_STATIC)
|
||||||
set(ENABLE_STATIC ON)
|
set(ENABLE_STATIC ON)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(add_module lib)
|
|
||||||
if(ENABLE_SHARED)
|
|
||||||
add_library(${lib}_shared SHARED ${ARGN})
|
|
||||||
set_target_properties(${lib}_shared PROPERTIES OUTPUT_NAME ${lib})
|
|
||||||
endif()
|
|
||||||
if(ENABLE_STATIC)
|
|
||||||
add_library(${lib}_static STATIC ${ARGN})
|
|
||||||
if(NOT MSVC)
|
|
||||||
set_target_properties(${lib}_static PROPERTIES OUTPUT_NAME ${lib})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(install_module lib)
|
function(install_module lib)
|
||||||
if(TARGET ${lib}_shared)
|
if(TARGET ${lib}_shared)
|
||||||
set_target_properties(${lib}_shared PROPERTIES
|
set_target_properties(${lib}_shared PROPERTIES
|
||||||
|
|
|
@ -31,8 +31,8 @@ out = (subprocess.run(
|
||||||
|
|
||||||
errors = 0
|
errors = 0
|
||||||
for line in out.split("\n"):
|
for line in out.split("\n"):
|
||||||
# other/fun can do what it wants.
|
# other/fun and mallocfail can do what they want.
|
||||||
if "/fun/" in line:
|
if "/fun/" in line or "/mallocfail/" in line:
|
||||||
continue
|
continue
|
||||||
filename, include = line.split(":", 1)
|
filename, include = line.split(":", 1)
|
||||||
# We only check headers.
|
# We only check headers.
|
||||||
|
|
|
@ -60,6 +60,7 @@ RUN source .github/scripts/flags-coverage.sh \
|
||||||
-DSTRICT_ABI=ON \
|
-DSTRICT_ABI=ON \
|
||||||
-DAUTOTEST=ON \
|
-DAUTOTEST=ON \
|
||||||
-DPROXY_TEST=ON \
|
-DPROXY_TEST=ON \
|
||||||
|
-DBUILD_FUZZ_TESTS=ON \
|
||||||
-DUSE_IPV6=OFF \
|
-DUSE_IPV6=OFF \
|
||||||
-DTEST_TIMEOUT_SECONDS=40 \
|
-DTEST_TIMEOUT_SECONDS=40 \
|
||||||
&& cmake --build _build --parallel 8 --target install
|
&& cmake --build _build --parallel 8 --target install
|
||||||
|
|
|
@ -1,26 +1,33 @@
|
||||||
# For coverage tests
|
|
||||||
target_compile_definitions(toxcore_static PUBLIC "FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION")
|
|
||||||
|
|
||||||
# Override network and random functions
|
# Override network and random functions
|
||||||
add_library(fuzz_support func_conversion.h fuzz_support.cc fuzz_support.h)
|
add_library(fuzz_support func_conversion.h fuzz_support.cc fuzz_support.h)
|
||||||
|
|
||||||
set(LIBFUZZER_LINKER_FLAGS)
|
set(LIBFUZZER_LINKER_FLAGS)
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||||
set(LIBFUZZER_LINKER_FLAGS "-fsanitize=fuzzer")
|
set(LIBFUZZER_LINKER_FLAGS "-fsanitize=fuzzer")
|
||||||
else()
|
else()
|
||||||
message(SEND_ERROR "Compiler must be Clang to build fuzz targets")
|
message(SEND_ERROR "Compiler must be Clang to build fuzz targets")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
function(fuzz_test target source_dir)
|
||||||
|
set(${target}_CORPUS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/toktok-fuzzer/corpus/${target}_fuzz_test)
|
||||||
|
file(GLOB ${target}_fuzz_CORPUS "${${target}_CORPUS_DIR}/*")
|
||||||
|
add_executable(${target}_fuzz_test ${source_dir}/${target}_fuzz_test.cc)
|
||||||
|
target_link_libraries(${target}_fuzz_test PRIVATE toxcore_fuzz fuzz_support ${LIBFUZZER_LINKER_FLAGS})
|
||||||
|
if(${target}_fuzz_CORPUS)
|
||||||
|
add_test(NAME ${target}_fuzz COMMAND ${CROSSCOMPILING_EMULATOR} ${target}_fuzz_test -max_total_time=10 ${${target}_fuzz_CORPUS})
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
# Fuzzes the toxsave API
|
# Fuzzes the toxsave API
|
||||||
add_executable(toxsave_fuzzer toxsave_harness.cc)
|
add_executable(toxsave_fuzzer toxsave_harness.cc)
|
||||||
target_link_libraries(toxsave_fuzzer PRIVATE toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})
|
target_link_libraries(toxsave_fuzzer PRIVATE toxcore_fuzz fuzz_support ${LIBFUZZER_LINKER_FLAGS})
|
||||||
|
|
||||||
# Fuzzes the bootstrap process
|
# Fuzzes the bootstrap process
|
||||||
add_executable(bootstrap_fuzzer bootstrap_harness.cc)
|
add_executable(bootstrap_fuzzer bootstrap_harness.cc)
|
||||||
target_link_libraries(bootstrap_fuzzer PRIVATE toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})
|
target_link_libraries(bootstrap_fuzzer PRIVATE toxcore_fuzz fuzz_support ${LIBFUZZER_LINKER_FLAGS})
|
||||||
|
|
||||||
add_executable(DHT_fuzz_test ../../toxcore/DHT_fuzz_test.cc)
|
fuzz_test(DHT ../../toxcore)
|
||||||
target_link_libraries(DHT_fuzz_test PRIVATE toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})
|
fuzz_test(forwarding ../../toxcore)
|
||||||
|
fuzz_test(group_announce ../../toxcore)
|
||||||
add_executable(tox_events_fuzz_test ../../toxcore/tox_events_fuzz_test.cc)
|
fuzz_test(group_moderation ../../toxcore)
|
||||||
target_link_libraries(tox_events_fuzz_test PRIVATE toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})
|
fuzz_test(tox_events ../../toxcore)
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -28,13 +29,20 @@ struct Fuzz_Data {
|
||||||
Fuzz_Data &operator=(const Fuzz_Data &rhs) = delete;
|
Fuzz_Data &operator=(const Fuzz_Data &rhs) = delete;
|
||||||
Fuzz_Data(const Fuzz_Data &rhs) = delete;
|
Fuzz_Data(const Fuzz_Data &rhs) = delete;
|
||||||
|
|
||||||
uint8_t consume1()
|
struct Consumer {
|
||||||
|
Fuzz_Data &fd;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
operator T()
|
||||||
{
|
{
|
||||||
const uint8_t val = data[0];
|
const uint8_t *bytes = fd.consume(sizeof(T));
|
||||||
++data;
|
T val;
|
||||||
--size;
|
std::memcpy(&val, bytes, sizeof(T));
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Consumer consume1() { return Consumer{*this}; }
|
||||||
|
|
||||||
const uint8_t *consume(std::size_t count)
|
const uint8_t *consume(std::size_t count)
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,6 +88,7 @@ cc_test(
|
||||||
srcs = ["util_test.cc"],
|
srcs = ["util_test.cc"],
|
||||||
deps = [
|
deps = [
|
||||||
":crypto_core",
|
":crypto_core",
|
||||||
|
":crypto_core_test_util",
|
||||||
":util",
|
":util",
|
||||||
"@com_google_googletest//:gtest",
|
"@com_google_googletest//:gtest",
|
||||||
"@com_google_googletest//:gtest_main",
|
"@com_google_googletest//:gtest_main",
|
||||||
|
|
|
@ -12,7 +12,8 @@ namespace {
|
||||||
void TestUnpackAnnouncesList(Fuzz_Data &input)
|
void TestUnpackAnnouncesList(Fuzz_Data &input)
|
||||||
{
|
{
|
||||||
CONSUME1_OR_RETURN(const uint8_t max_count, input);
|
CONSUME1_OR_RETURN(const uint8_t max_count, input);
|
||||||
std::vector<GC_Announce> announces(max_count);
|
// Always allocate at least something to avoid passing nullptr to functions below.
|
||||||
|
std::vector<GC_Announce> announces(max_count + 1);
|
||||||
|
|
||||||
// TODO(iphydf): How do we know the packed size?
|
// TODO(iphydf): How do we know the packed size?
|
||||||
CONSUME1_OR_RETURN(const uint16_t packed_size, input);
|
CONSUME1_OR_RETURN(const uint16_t packed_size, input);
|
||||||
|
@ -20,10 +21,11 @@ void TestUnpackAnnouncesList(Fuzz_Data &input)
|
||||||
Logger *logger = logger_new();
|
Logger *logger = logger_new();
|
||||||
if (gca_unpack_announces_list(logger, input.data, input.size, announces.data(), max_count)
|
if (gca_unpack_announces_list(logger, input.data, input.size, announces.data(), max_count)
|
||||||
!= -1) {
|
!= -1) {
|
||||||
std::vector<uint8_t> packed(packed_size);
|
// Always allocate at least something to avoid passing nullptr to functions below.
|
||||||
|
std::vector<uint8_t> packed(packed_size + 1);
|
||||||
size_t processed;
|
size_t processed;
|
||||||
gca_pack_announces_list(
|
gca_pack_announces_list(
|
||||||
logger, packed.data(), packed.size(), announces.data(), announces.size(), &processed);
|
logger, packed.data(), packed_size, announces.data(), max_count, &processed);
|
||||||
}
|
}
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
}
|
}
|
||||||
|
@ -37,8 +39,9 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input)
|
||||||
|
|
||||||
Logger *logger = logger_new();
|
Logger *logger = logger_new();
|
||||||
if (gca_unpack_public_announce(logger, input.data, input.size, &public_announce) != -1) {
|
if (gca_unpack_public_announce(logger, input.data, input.size, &public_announce) != -1) {
|
||||||
std::vector<uint8_t> packed(packed_size);
|
// Always allocate at least something to avoid passing nullptr to functions below.
|
||||||
gca_pack_public_announce(logger, packed.data(), packed.size(), &public_announce);
|
std::vector<uint8_t> packed(packed_size + 1);
|
||||||
|
gca_pack_public_announce(logger, packed.data(), packed_size, &public_announce);
|
||||||
}
|
}
|
||||||
logger_kill(logger);
|
logger_kill(logger);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include "crypto_core.h"
|
#include "crypto_core.h"
|
||||||
|
#include "crypto_core_test_util.hh"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
TEST(Util, TwoRandomIdsAreNotEqual)
|
TEST(Util, TwoRandomIdsAreNotEqual)
|
||||||
{
|
{
|
||||||
const Random *rng = system_random();
|
Test_Random rng;
|
||||||
ASSERT_NE(rng, nullptr);
|
|
||||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||||
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
||||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
|
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE];
|
||||||
|
@ -23,8 +23,7 @@ TEST(Util, TwoRandomIdsAreNotEqual)
|
||||||
|
|
||||||
TEST(Util, IdCopyMakesKeysEqual)
|
TEST(Util, IdCopyMakesKeysEqual)
|
||||||
{
|
{
|
||||||
const Random *rng = system_random();
|
Test_Random rng;
|
||||||
ASSERT_NE(rng, nullptr);
|
|
||||||
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
|
||||||
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
uint8_t sk1[CRYPTO_SECRET_KEY_SIZE];
|
||||||
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
|
uint8_t pk2[CRYPTO_PUBLIC_KEY_SIZE] = {0};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user