Coverage Report

Created: 2025-10-08 19:34

/work/toxcore/forwarding_fuzz_test.cc
Line
Count
Source
1
#include "forwarding.h"
2
3
#include <cassert>
4
#include <cstring>
5
#include <memory>
6
#include <optional>
7
8
#include "../testing/fuzzing/fuzz_support.hh"
9
#include "../testing/fuzzing/fuzz_tox.hh"
10
11
namespace {
12
13
std::optional<std::tuple<IP_Port, IP_Port, const uint8_t *, size_t>> prepare(Fuzz_Data &input)
14
48
{
15
48
    CONSUME_OR_RETURN_VAL(const uint8_t *ipp_packed, input, SIZE_IP_PORT, std::nullopt);
16
46
    IP_Port ipp{};
17
46
    unpack_ip_port(&ipp, ipp_packed, SIZE_IP6, true);
18
19
46
    CONSUME_OR_RETURN_VAL(const uint8_t *forwarder_packed, input, SIZE_IP_PORT, std::nullopt);
20
41
    IP_Port forwarder{};
21
41
    unpack_ip_port(&forwarder, forwarder_packed, SIZE_IP6, true);
22
23
    // 2 bytes: size of the request
24
41
    CONSUME_OR_RETURN_VAL(const uint8_t *data_size_bytes, input, sizeof(uint16_t), std::nullopt);
25
35
    uint16_t data_size;
26
35
    std::memcpy(&data_size, data_size_bytes, sizeof(uint16_t));
27
28
    // data bytes (max 64K)
29
35
    CONSUME_OR_RETURN_VAL(const uint8_t *data, input, data_size, std::nullopt);
30
31
33
    return {{ipp, forwarder, data, data_size}};
32
35
}
33
34
void TestSendForwardRequest(Fuzz_Data &input)
35
26
{
36
26
    CONSUME1_OR_RETURN(const uint16_t, chain_length, input);
37
25
    const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE;
38
25
    CONSUME_OR_RETURN(const uint8_t *chain_keys, input, chain_keys_size);
39
40
24
    const auto prep = prepare(input);
41
24
    if (!prep.has_value()) {
42
4
        return;
43
4
    }
44
20
    const auto [ipp, forwarder, data, data_size] = prep.value();
45
46
    // rest of the fuzz data is input for malloc and network
47
20
    Fuzz_System sys(input);
48
49
20
    const Ptr<Logger> logger(logger_new(sys.mem.get()), logger_kill);
50
20
    if (logger == nullptr) {
51
1
        return;
52
1
    }
53
54
19
    const Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(),
55
19
                                       &ipp.ip, ipp.port, ipp.port + 100, nullptr),
56
19
        kill_networking);
57
19
    if (net == nullptr) {
58
1
        return;
59
1
    }
60
61
18
    send_forward_request(net.get(), &forwarder, chain_keys, chain_length, data, data_size);
62
18
}
63
64
void TestForwardReply(Fuzz_Data &input)
65
26
{
66
26
    CONSUME1_OR_RETURN(const uint16_t, sendback_length, input);
67
25
    CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length);
68
69
24
    const auto prep = prepare(input);
70
24
    if (!prep.has_value()) {
71
11
        return;
72
11
    }
73
13
    const auto [ipp, forwarder, data, data_size] = prep.value();
74
75
    // rest of the fuzz data is input for malloc and network
76
13
    Fuzz_System sys(input);
77
78
13
    const Ptr<Logger> logger(logger_new(sys.mem.get()), logger_kill);
79
13
    if (logger == nullptr) {
80
1
        return;
81
1
    }
82
83
12
    const Ptr<Networking_Core> net(new_networking_ex(logger.get(), sys.mem.get(), sys.ns.get(),
84
12
                                       &ipp.ip, ipp.port, ipp.port + 100, nullptr),
85
12
        kill_networking);
86
12
    if (net == nullptr) {
87
3
        return;
88
3
    }
89
90
9
    forward_reply(net.get(), &forwarder, sendback, sendback_length, data, data_size);
91
9
}
92
93
}  // namespace
94
95
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
96
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
97
2.57k
{
98
2.57k
    fuzz_select_target<TestSendForwardRequest, TestForwardReply>(data, size);
99
2.57k
    return 0;
100
2.57k
}