Coverage Report

Created: 2024-01-26 01:52

/work/testing/fuzzing/bootstrap_fuzz_test.cc
Line
Count
Source (jump to first uncovered line)
1
#include <cassert>
2
#include <cstdio>
3
4
#include "../../toxcore/tox.h"
5
#include "../../toxcore/tox_dispatch.h"
6
#include "../../toxcore/tox_events.h"
7
#include "fuzz_support.h"
8
#include "fuzz_tox.h"
9
10
namespace {
11
12
void setup_callbacks(Tox_Dispatch *dispatch)
13
755
{
14
755
    tox_events_callback_conference_connected(
15
755
        dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) {
16
0
            assert(event == nullptr);
17
0
        });
18
755
    tox_events_callback_conference_connected(
19
755
        dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) {
20
0
            assert(event == nullptr);
21
0
        });
22
755
    tox_events_callback_conference_invite(
23
755
        dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) {
24
0
            assert(event == nullptr);
25
0
        });
26
755
    tox_events_callback_conference_message(
27
755
        dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) {
28
0
            assert(event == nullptr);
29
0
        });
30
755
    tox_events_callback_conference_peer_list_changed(dispatch,
31
755
        [](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) {
32
0
            assert(event == nullptr);
33
0
        });
34
755
    tox_events_callback_conference_peer_name(
35
755
        dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) {
36
0
            assert(event == nullptr);
37
0
        });
38
755
    tox_events_callback_conference_title(
39
755
        dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) {
40
0
            assert(event == nullptr);
41
0
        });
42
755
    tox_events_callback_file_chunk_request(
43
755
        dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) {
44
0
            assert(event == nullptr);
45
0
        });
46
755
    tox_events_callback_file_recv(
47
755
        dispatch, [](Tox *tox, const Tox_Event_File_Recv *event, void *user_data) {
48
0
            assert(event == nullptr);
49
0
        });
50
755
    tox_events_callback_file_recv_chunk(
51
755
        dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) {
52
0
            assert(event == nullptr);
53
0
        });
54
755
    tox_events_callback_file_recv_control(
55
755
        dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) {
56
0
            assert(event == nullptr);
57
0
        });
58
755
    tox_events_callback_friend_connection_status(
59
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) {
60
0
            assert(event == nullptr);
61
0
        });
62
755
    tox_events_callback_friend_lossless_packet(
63
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data) {
64
0
            assert(event == nullptr);
65
0
        });
66
755
    tox_events_callback_friend_lossy_packet(
67
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data) {
68
0
            assert(event == nullptr);
69
0
        });
70
755
    tox_events_callback_friend_message(
71
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) {
72
0
            assert(event == nullptr);
73
0
        });
74
755
    tox_events_callback_friend_name(
75
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Name *event, void *user_data) {
76
0
            assert(event == nullptr);
77
0
        });
78
755
    tox_events_callback_friend_read_receipt(
79
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data) {
80
0
            assert(event == nullptr);
81
0
        });
82
755
    tox_events_callback_friend_request(
83
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Request *event, void *user_data) {
84
8
            Tox_Err_Friend_Add err;
85
8
            tox_friend_add_norequest(tox, tox_event_friend_request_get_public_key(event), &err);
86
8
            if (!(err == TOX_ERR_FRIEND_ADD_OK || err == TOX_ERR_FRIEND_ADD_OWN_KEY
87
8
                    || err == TOX_ERR_FRIEND_ADD_ALREADY_SENT
88
8
                    || err == TOX_ERR_FRIEND_ADD_BAD_CHECKSUM
89
8
                    || err == TOX_ERR_FRIEND_ADD_MALLOC)) {
90
0
                printf("unexpected error: %s\n", tox_err_friend_add_to_string(err));
91
0
            }
92
8
        });
93
755
    tox_events_callback_friend_status(
94
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Status *event, void *user_data) {
95
0
            assert(event == nullptr);
96
0
        });
97
755
    tox_events_callback_friend_status_message(
98
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data) {
99
0
            assert(event == nullptr);
100
0
        });
101
755
    tox_events_callback_friend_typing(
102
755
        dispatch, [](Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data) {
103
0
            assert(event == nullptr);
104
0
        });
105
755
    tox_events_callback_self_connection_status(
106
755
        dispatch, [](Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data) {
107
0
            assert(event == nullptr);
108
0
        });
109
755
}
110
111
void TestBootstrap(Fuzz_Data &input)
112
805
{
113
    // Null system for regularly working memory allocations needed in
114
    // tox_events_equal.
115
805
    Null_System null_sys;
116
805
    Fuzz_System sys(input);
117
118
805
    Ptr<Tox_Options> opts(tox_options_new(nullptr), tox_options_free);
119
805
    assert(opts != nullptr);
120
805
    tox_options_set_operating_system(opts.get(), sys.sys.get());
121
122
805
    tox_options_set_log_callback(opts.get(),
123
805
        [](Tox *tox, Tox_Log_Level level, const char *file, uint32_t line, const char *func,
124
58.2k
            const char *message, void *user_data) {
125
            // Log to stdout.
126
58.2k
            if (Fuzz_Data::DEBUG) {
127
0
                std::printf("[tox1] %c %s:%d(%s): %s\n", tox_log_level_name(level), file, line,
128
0
                    func, message);
129
0
            }
130
58.2k
        });
131
132
805
    CONSUME1_OR_RETURN(const uint8_t, proxy_type, input);
133
805
    if (proxy_type == 0) {
134
38
        tox_options_set_proxy_type(opts.get(), TOX_PROXY_TYPE_NONE);
135
767
    } else if (proxy_type == 1) {
136
38
        tox_options_set_proxy_type(opts.get(), TOX_PROXY_TYPE_SOCKS5);
137
38
        tox_options_set_proxy_host(opts.get(), "127.0.0.1");
138
38
        tox_options_set_proxy_port(opts.get(), 8080);
139
729
    } else if (proxy_type == 2) {
140
145
        tox_options_set_proxy_type(opts.get(), TOX_PROXY_TYPE_HTTP);
141
145
        tox_options_set_proxy_host(opts.get(), "127.0.0.1");
142
145
        tox_options_set_proxy_port(opts.get(), 8080);
143
145
    }
144
145
805
    CONSUME1_OR_RETURN(const uint8_t, tcp_relay_enabled, input);
146
801
    if (tcp_relay_enabled >= (UINT8_MAX / 2)) {
147
41
        tox_options_set_tcp_port(opts.get(), 33445);
148
41
    }
149
150
801
    Tox_Err_New error_new;
151
801
    Tox *tox = tox_new(opts.get(), &error_new);
152
153
801
    if (tox == nullptr) {
154
        // It might fail, because some I/O happens in tox_new, and the fuzzer
155
        // might do things that make that I/O fail.
156
46
        return;
157
46
    }
158
159
755
    assert(error_new == TOX_ERR_NEW_OK);
160
161
755
    uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0};
162
163
    // These may fail, but that's ok. We ignore their return values.
164
755
    tox_bootstrap(tox, "127.0.0.2", 33446, pub_key, nullptr);
165
755
    tox_add_tcp_relay(tox, "127.0.0.2", 33446, pub_key, nullptr);
166
167
755
    tox_events_init(tox);
168
169
755
    Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
170
755
    assert(dispatch != nullptr);
171
755
    setup_callbacks(dispatch);
172
173
63.9k
    while (!input.empty()) {
174
63.2k
        Tox_Err_Events_Iterate error_iterate;
175
63.2k
        Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
176
63.2k
        assert(tox_events_equal(null_sys.sys.get(), events, events));
177
63.2k
        tox_dispatch_invoke(dispatch, events, tox, nullptr);
178
63.2k
        tox_events_free(events);
179
        // Move the clock forward a decent amount so all the time-based checks
180
        // trigger more quickly.
181
63.2k
        sys.clock += 200;
182
63.2k
    }
183
184
755
    tox_dispatch_free(dispatch);
185
755
    tox_kill(tox);
186
755
}
187
188
}
189
190
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
191
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
192
2.99k
{
193
2.99k
    Fuzz_Data input{data, size};
194
2.99k
    TestBootstrap(input);
195
2.99k
    return 0;  // Non-zero return values are reserved for future use.
196
2.99k
}