/work/toxcore/net_crypto_fuzz_test.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "net_crypto.h" |
2 | | |
3 | | #include <cassert> |
4 | | #include <cstddef> |
5 | | #include <cstring> |
6 | | #include <functional> |
7 | | #include <memory> |
8 | | #include <optional> |
9 | | |
10 | | #include "../testing/support/public/fuzz_data.hh" |
11 | | #include "../testing/support/public/fuzz_helpers.hh" |
12 | | #include "../testing/support/public/simulated_environment.hh" |
13 | | #include "DHT.h" |
14 | | #include "TCP_client.h" |
15 | | #include "attributes.h" |
16 | | #include "net_profile.h" |
17 | | #include "network.h" |
18 | | |
19 | | namespace { |
20 | | |
21 | | using tox::test::configure_fuzz_memory_source; |
22 | | using tox::test::FakeClock; |
23 | | using tox::test::Fuzz_Data; |
24 | | using tox::test::SimulatedEnvironment; |
25 | | |
26 | | template <typename T> |
27 | | using Ptr = std::unique_ptr<T, void (*)(T *)>; |
28 | | |
29 | | std::optional<std::tuple<IP_Port, std::uint8_t>> prepare(Fuzz_Data &input) |
30 | 44 | { |
31 | 44 | IP_Port ipp; |
32 | 44 | ip_init(&ipp.ip, true); |
33 | 44 | ipp.port = net_htons(33445); |
34 | | |
35 | 44 | CONSUME_OR_RETURN_VAL(const std::uint8_t *iterations_packed, input, 1, std::nullopt); |
36 | 43 | std::uint8_t iterations = *iterations_packed; |
37 | | |
38 | 43 | return {{ipp, iterations}}; |
39 | 44 | } |
40 | | |
41 | | static constexpr Net_Crypto_DHT_Funcs dht_funcs = { |
42 | 0 | [](void *_Nonnull dht, const std::uint8_t *_Nonnull public_key) { |
43 | 0 | return dht_get_shared_key_sent(static_cast<DHT *>(dht), public_key); |
44 | 0 | }, |
45 | 0 | [](const void *_Nonnull dht) { return dht_get_self_public_key(static_cast<const DHT *>(dht)); }, |
46 | 25 | [](const void *_Nonnull dht) { return dht_get_self_secret_key(static_cast<const DHT *>(dht)); }, |
47 | | }; |
48 | | |
49 | | void TestNetCrypto(Fuzz_Data &input) |
50 | 44 | { |
51 | 44 | const auto prep = prepare(input); |
52 | 44 | if (!prep.has_value()) { |
53 | 1 | return; |
54 | 1 | } |
55 | 43 | const auto [ipp, iterations] = prep.value(); |
56 | | |
57 | 43 | SimulatedEnvironment env{12345}; |
58 | 43 | env.fake_clock().advance(1000000000); // Start clock high to match legacy behavior |
59 | 43 | auto node = env.create_node(ipp.port); |
60 | 43 | configure_fuzz_memory_source(env.fake_memory(), input); |
61 | | |
62 | 43 | const Ptr<Logger> logger(logger_new(&node->c_memory), logger_kill); |
63 | 43 | if (logger == nullptr) { |
64 | 1 | return; |
65 | 1 | } |
66 | | |
67 | 42 | const Ptr<Networking_Core> net( |
68 | 42 | new_networking_ex(logger.get(), &node->c_memory, &node->c_network, &ipp.ip, ipp.port, |
69 | 42 | ipp.port + 100, nullptr), |
70 | 42 | kill_networking); |
71 | 42 | if (net == nullptr) { |
72 | 2 | return; |
73 | 2 | } |
74 | | |
75 | 40 | const std::unique_ptr<Mono_Time, std::function<void(Mono_Time *)>> mono_time( |
76 | 40 | mono_time_new( |
77 | 40 | &node->c_memory, |
78 | 2.37k | [](void *_Nullable user_data) { |
79 | 2.37k | return static_cast<FakeClock *>(user_data)->current_time_ms(); |
80 | 2.37k | }, |
81 | 40 | &env.fake_clock()), |
82 | 40 | [&node](Mono_Time *ptr) { mono_time_free(&node->c_memory, ptr); }); |
83 | | |
84 | 40 | if (mono_time == nullptr) { |
85 | 2 | return; |
86 | 2 | } |
87 | | |
88 | 38 | const Ptr<DHT> dht(new_dht(logger.get(), &node->c_memory, &node->c_random, &node->c_network, |
89 | 38 | mono_time.get(), net.get(), false, false), |
90 | 38 | kill_dht); |
91 | 38 | if (dht == nullptr) { |
92 | 11 | return; |
93 | 11 | } |
94 | | |
95 | 27 | Net_Profile *tcp_np = netprof_new(logger.get(), &node->c_memory); |
96 | | |
97 | 27 | if (tcp_np == nullptr) { |
98 | 1 | return; |
99 | 1 | } |
100 | | |
101 | 26 | const TCP_Proxy_Info proxy_info = {0}; |
102 | | |
103 | 26 | const Ptr<Net_Crypto> net_crypto( |
104 | 26 | new_net_crypto(logger.get(), &node->c_memory, &node->c_random, &node->c_network, |
105 | 26 | mono_time.get(), net.get(), dht.get(), &dht_funcs, &proxy_info, tcp_np), |
106 | 26 | kill_net_crypto); |
107 | 26 | if (net_crypto == nullptr) { |
108 | 2 | netprof_kill(&node->c_memory, tcp_np); |
109 | 2 | return; |
110 | 2 | } |
111 | | |
112 | 2.36k | for (std::uint8_t i = 0; i < iterations; ++i) { |
113 | 2.33k | networking_poll(net.get(), nullptr); |
114 | 2.33k | do_dht(dht.get()); |
115 | 2.33k | do_net_crypto(net_crypto.get(), nullptr); |
116 | | |
117 | 2.33k | env.advance_time(200); |
118 | 2.33k | } |
119 | | |
120 | 24 | netprof_kill(&node->c_memory, tcp_np); |
121 | 24 | } |
122 | | |
123 | | } // namespace |
124 | | |
125 | | extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size); |
126 | | extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t *data, std::size_t size) |
127 | 2.69k | { |
128 | 2.69k | tox::test::fuzz_select_target<TestNetCrypto>(data, size); |
129 | 2.69k | return 0; |
130 | 2.69k | } |