Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup: Some more test cleanups, removing overly smart code. #2536

Merged
merged 1 commit into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions testing/fuzzing/e2e_fuzz_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <fstream>
#include <vector>

#include "../../toxcore/crypto_core.h"
#include "../../toxcore/tox.h"
#include "../../toxcore/tox_dispatch.h"
#include "../../toxcore/tox_events.h"
Expand Down
10 changes: 10 additions & 0 deletions testing/fuzzing/fuzz_support.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ struct Network_Addr {
size_t size;
};

System::System(std::unique_ptr<Tox_System> in_sys, std::unique_ptr<Memory> in_mem,
std::unique_ptr<Network> in_ns, std::unique_ptr<Random> in_rng)
: sys(std::move(in_sys))
, mem(std::move(in_mem))
, ns(std::move(in_ns))
, rng(std::move(in_rng))
{
}
System::System(System &&) = default;

System::~System() { }

static int recv_common(Fuzz_Data &input, uint8_t *buf, size_t buf_len)
Expand Down
22 changes: 17 additions & 5 deletions testing/fuzzing/fuzz_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
#include <cstdlib>
#include <deque>
#include <memory>
#include <vector>
#include <unordered_map>
#include <utility>
#include <vector>

#include "../../toxcore/tox.h"

Expand All @@ -20,8 +20,10 @@ struct Fuzz_Data {
std::size_t size;

Fuzz_Data(const uint8_t *input_data, std::size_t input_size)
: data(input_data), size(input_size)
{}
: data(input_data)
, size(input_size)
{
}

Fuzz_Data &operator=(const Fuzz_Data &rhs) = delete;
Fuzz_Data(const Fuzz_Data &rhs) = delete;
Expand Down Expand Up @@ -93,14 +95,20 @@ struct Fuzz_Data {
} \
DECL = INPUT.consume(SIZE)

#define CONSUME_OR_RETURN_VAL(DECL, INPUT, SIZE, VAL) \
if (INPUT.size < SIZE) { \
return VAL; \
} \
DECL = INPUT.consume(SIZE)

inline void fuzz_select_target(uint8_t selector, Fuzz_Data &input)
{
// The selector selected no function, so we do nothing and rely on the
// fuzzer to come up with a better selector.
}

template <typename Arg, typename... Args>
void fuzz_select_target(uint8_t selector, Fuzz_Data &input, Arg &&fn, Args &&... args)
void fuzz_select_target(uint8_t selector, Fuzz_Data &input, Arg &&fn, Args &&...args)
{
if (selector == sizeof...(Args)) {
return fn(input);
Expand All @@ -109,7 +117,7 @@ void fuzz_select_target(uint8_t selector, Fuzz_Data &input, Arg &&fn, Args &&...
}

template <typename... Args>
void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&... args)
void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&...args)
{
Fuzz_Data input{data, size};

Expand All @@ -127,6 +135,10 @@ struct System {
std::unique_ptr<Network> ns;
std::unique_ptr<Random> rng;

System(std::unique_ptr<Tox_System> sys, std::unique_ptr<Memory> mem,
std::unique_ptr<Network> ns, std::unique_ptr<Random> rng);
System(System &&);

// Not inline because sizeof of the above 2 structs is not known everywhere.
~System();

Expand Down
81 changes: 1 addition & 80 deletions testing/fuzzing/fuzz_tox.h
Original file line number Diff line number Diff line change
@@ -1,96 +1,17 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2022 The TokTok team.
* Copyright © 2022-2024 The TokTok team.
*/

#ifndef C_TOXCORE_TESTING_FUZZING_FUZZ_TOX_H
#define C_TOXCORE_TESTING_FUZZING_FUZZ_TOX_H

#include <cassert>
#include <memory>

#include "../../toxcore/DHT.h"
#include "../../toxcore/logger.h"
#include "../../toxcore/network.h"
#include "fuzz_support.h"

constexpr uint16_t SIZE_IP_PORT = SIZE_IP6 + sizeof(uint16_t);

template <typename T>
using Ptr = std::unique_ptr<T, void (*)(T *)>;

/** @brief Construct any Tox resource using fuzzer input data.
*
* Constructs (or fails by returning) a valid object of type T and passes it to
* a function specified on the rhs of `>>`. Takes care of cleaning up the
* resource after the specified function returns.
*
* Some `with` instances require additional inputs such as the `Fuzz_Data`
* reference or a logger.
*/
template <typename T>
struct with;

/** @brief Construct a Logger without logging callback.
*/
template <>
struct with<Logger> {
template <typename F>
void operator>>(F &&f)
{
Ptr<Logger> logger(logger_new(), logger_kill);
assert(logger != nullptr);
f(std::move(logger));
}
};

/** @brief Construct an IP_Port by unpacking fuzzer input with `unpack_ip_port`.
*/
template <>
struct with<IP_Port> {
Fuzz_Data &input_;

template <typename F>
void operator>>(F &&f)
{
CONSUME_OR_RETURN(const uint8_t *ipp_packed, input_, SIZE_IP_PORT);
IP_Port ipp;
unpack_ip_port(&ipp, ipp_packed, SIZE_IP6, true);

f(ipp);
}
};

/** @brief Construct a Networking_Core object using the Network vtable passed.
*
* Use `with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> ...` to construct
* a logger and pass it to the Networking_Core constructor function.
*/
template <>
struct with<Networking_Core> {
Fuzz_Data &input_;
const Network *ns_;
const Memory *mem_;
Ptr<Logger> logger_{nullptr, logger_kill};

friend with operator>>(with<Logger> f, with self)
{
f >> [&self](Ptr<Logger> logger) { self.logger_ = std::move(logger); };
return self;
}

template <typename F>
void operator>>(F &&f)
{
with<IP_Port>{input_} >> [&f, this](const IP_Port &ipp) {
Ptr<Networking_Core> net(
new_networking_ex(logger_.get(), mem_, ns_, &ipp.ip, ipp.port, ipp.port + 100, nullptr),
kill_networking);
if (net == nullptr) {
return;
}
f(std::move(net));
};
}
};

#endif // C_TOXCORE_TESTING_FUZZING_FUZZ_TOX_H
1 change: 1 addition & 0 deletions testing/fuzzing/protodump_reduce.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <cassert>
#include <cstdio>

#include "../../toxcore/crypto_core.h"
#include "../../toxcore/tox.h"
#include "../../toxcore/tox_dispatch.h"
#include "../../toxcore/tox_events.h"
Expand Down
1 change: 1 addition & 0 deletions toxcore/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ cc_library(
deps = [
":crypto_core",
":network",
":test_util",
],
)

Expand Down
26 changes: 13 additions & 13 deletions toxcore/DHT_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,13 @@ TEST(AnnounceNodes, SetAndTest)
ASSERT_NE(log, nullptr);
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
ASSERT_NE(mono_time, nullptr);
Networking_Core *net = new_networking_no_udp(log, mem, ns);
Ptr<Networking_Core> net(new_networking_no_udp(log, mem, ns));
Green-Sky marked this conversation as resolved.
Show resolved Hide resolved
ASSERT_NE(net, nullptr);
DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true);
Ptr<DHT> dht(new_dht(log, mem, rng, ns, mono_time, net.get(), true, true));
ASSERT_NE(dht, nullptr);

uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE];
memcpy(pk_data, dht_get_self_public_key(dht), sizeof(pk_data));
memcpy(pk_data, dht_get_self_public_key(dht.get()), sizeof(pk_data));
PublicKey self_pk(to_array(pk_data));

PublicKey pk1 = random_pk(rng);
Expand All @@ -353,20 +353,20 @@ TEST(AnnounceNodes, SetAndTest)
IP_Port ip_port = {0};
ip_port.ip.family = net_family_ipv4();

set_announce_node(dht, pk1.data());
set_announce_node(dht, pk2.data());
set_announce_node(dht.get(), pk1.data());
set_announce_node(dht.get(), pk2.data());

EXPECT_TRUE(addto_lists(dht, &ip_port, pk1.data()));
EXPECT_TRUE(addto_lists(dht, &ip_port, pk2.data()));
EXPECT_TRUE(addto_lists(dht.get(), &ip_port, pk1.data()));
EXPECT_TRUE(addto_lists(dht.get(), &ip_port, pk2.data()));

Node_format nodes[MAX_SENT_NODES];
EXPECT_EQ(0, get_close_nodes(dht, self_pk.data(), nodes, net_family_unspec(), true, true));
set_announce_node(dht, pk1.data());
set_announce_node(dht, pk2.data());
EXPECT_EQ(2, get_close_nodes(dht, self_pk.data(), nodes, net_family_unspec(), true, true));
EXPECT_EQ(
0, get_close_nodes(dht.get(), self_pk.data(), nodes, net_family_unspec(), true, true));
set_announce_node(dht.get(), pk1.data());
set_announce_node(dht.get(), pk2.data());
EXPECT_EQ(
2, get_close_nodes(dht.get(), self_pk.data(), nodes, net_family_unspec(), true, true));

kill_dht(dht);
kill_networking(net);
mono_time_free(mem, mono_time);
logger_kill(log);
}
Expand Down
4 changes: 4 additions & 0 deletions toxcore/DHT_test_util.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#include <iosfwd>

#include "DHT.h"
#include "test_util.hh"

template <>
struct Deleter<DHT> : Function_Deleter<DHT, kill_dht> { };

bool operator==(Node_format const &a, Node_format const &b);

Expand Down
96 changes: 68 additions & 28 deletions toxcore/forwarding_fuzz_test.cc
Original file line number Diff line number Diff line change
@@ -1,47 +1,87 @@
#include "forwarding.h"

#include <cassert>
#include <cstring>
#include <memory>
#include <optional>

#include "../testing/fuzzing/fuzz_support.h"
#include "../testing/fuzzing/fuzz_tox.h"

namespace {

std::optional<std::tuple<IP_Port, IP_Port, const uint8_t *, size_t>> prepare(Fuzz_Data &input)
{
CONSUME_OR_RETURN_VAL(const uint8_t *ipp_packed, input, SIZE_IP_PORT, std::nullopt);
IP_Port ipp;
unpack_ip_port(&ipp, ipp_packed, SIZE_IP6, true);

CONSUME_OR_RETURN_VAL(const uint8_t *forwarder_packed, input, SIZE_IP_PORT, std::nullopt);
IP_Port forwarder;
unpack_ip_port(&forwarder, forwarder_packed, SIZE_IP6, true);

// 2 bytes: size of the request
CONSUME_OR_RETURN_VAL(const uint8_t *data_size_bytes, input, sizeof(uint16_t), std::nullopt);
uint16_t data_size;
std::memcpy(&data_size, data_size_bytes, sizeof(uint16_t));

// data bytes (max 64K)
CONSUME_OR_RETURN_VAL(const uint8_t *data, input, data_size, std::nullopt);

return {{ipp, forwarder, data, data_size}};
}

void TestSendForwardRequest(Fuzz_Data &input)
{
const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr);
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
assert(mem != nullptr);

with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t chain_length, input);
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size);

send_forward_request(
net.get(), &forwarder, chain_keys, chain_length, input.data, input.size);
};
};
CONSUME1_OR_RETURN(const uint16_t chain_length, input);
const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size);

auto prep = prepare(input);
if (!prep.has_value()) {
return;
}
auto [ipp, forwarder, data, data_size] = prep.value();

// rest of the fuzz data is input for malloc and network
Fuzz_System sys(input);

Ptr<Logger> logger(logger_new(), logger_kill);

Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip,
ipp.port, ipp.port + 100, nullptr),
kill_networking);
if (net == nullptr) {
return;
}

send_forward_request(net.get(), &forwarder, chain_keys, chain_length, data, data_size);
}

void TestForwardReply(Fuzz_Data &input)
{
const Network *ns = system_network(); // TODO(iphydf): fuzz_network
assert(ns != nullptr);
const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory
assert(mem != nullptr);

with<Logger>{} >> with<Networking_Core>{input, ns, mem} >> [&input](Ptr<Networking_Core> net) {
with<IP_Port>{input} >> [net = std::move(net), &input](const IP_Port &forwarder) {
CONSUME1_OR_RETURN(const uint16_t sendback_length, input);
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);

forward_reply(net.get(), &forwarder, sendback, sendback_length, input.data, input.size);
};
};
CONSUME1_OR_RETURN(const uint16_t sendback_length, input);
CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);

auto prep = prepare(input);
if (!prep.has_value()) {
return;
}
auto [ipp, forwarder, data, data_size] = prep.value();

// rest of the fuzz data is input for malloc and network
Fuzz_System sys(input);

Ptr<Logger> logger(logger_new(), logger_kill);

Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(), &ipp.ip,
ipp.port, ipp.port + 100, nullptr),
kill_networking);
if (net == nullptr) {
return;
}

forward_reply(net.get(), &forwarder, sendback, sendback_length, data, data_size);
}

} // namespace
Expand Down
6 changes: 5 additions & 1 deletion toxcore/network_test_util.hh
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#ifndef C_TOXCORE_TOXCORE_NETWORK_TEST_UTIL_H
#define C_TOXCORE_TOXCORE_NETWORK_TEST_UTIL_H

#include <ostream>
#include <iosfwd>

#include "crypto_core.h"
#include "network.h"
#include "test_util.hh"

template <>
struct Deleter<Networking_Core> : Function_Deleter<Networking_Core, kill_networking> { };

IP_Port random_ip_port(const Random *rng);

Expand Down
Loading
Loading