Skip to content

Commit

Permalink
test: Enable fuzzing for TCP.
Browse files Browse the repository at this point in the history
If the `recvbuf` network function returns 0 all the time, that means
there is never any data available on the TCP socket. This change makes
it so there is a random amount of data available on the TCP socket.

This invalidates the bootstrap fuzzer corpus.
  • Loading branch information
iphydf committed Apr 14, 2022
1 parent efea12e commit 8ec6d68
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 26 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ jobs:
- uses: actions/checkout@v2
with:
submodules: recursive
- uses: actions/setup-go@v3
with:
go-version: "1.16.15"
- name: Build, test, and upload coverage
run: .github/scripts/coverage-linux

Expand Down
2 changes: 1 addition & 1 deletion other/bootstrap_daemon/docker/tox-bootstrapd.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
f20ba5a6917e5faee9a2a6439b448d3ced7cd177ba666ff1804882f494ea7b90 /usr/local/bin/tox-bootstrapd
4302ebfb454cfd087a919ac41ea513e04a9cdddfd9518c9c1959058bc244c06f /usr/local/bin/tox-bootstrapd
5 changes: 5 additions & 0 deletions other/proxy/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/TokTok/c-toxcore/other/proxy

go 1.16

require github.com/things-go/go-socks5 v0.0.2
14 changes: 14 additions & 0 deletions other/proxy/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/things-go/go-socks5 v0.0.2 h1:dFi5iZ/LqgHRTQ6n3XlipTLDWHAQsejvJ300bH2VFWo=
github.com/things-go/go-socks5 v0.0.2/go.mod h1:dhnDTBbIg31cbJdROP4/Zz6Iw7JPEpiMvOl2LdHSSjE=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
38 changes: 29 additions & 9 deletions testing/fuzzing/bootstrap_harness.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,36 +108,47 @@ void setup_callbacks(Tox_Dispatch *dispatch)
});
}

}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
void TestBootstrap(Fuzz_Data &input)
{
Fuzz_Data input{data, size};

Fuzz_System sys(input);
assert(sys.rng != nullptr);

Tox_Options *opts = tox_options_new(nullptr);
assert(opts != nullptr);
tox_options_set_operating_system(opts, sys.sys.get());

CONSUME1_OR_RETURN(const uint8_t proxy_type, input);
if (proxy_type == 0) {
tox_options_set_proxy_type(opts, TOX_PROXY_TYPE_NONE);
} else if (proxy_type == 1) {
tox_options_set_proxy_type(opts, TOX_PROXY_TYPE_SOCKS5);
tox_options_set_proxy_host(opts, "127.0.0.1");
tox_options_set_proxy_port(opts, 8080);
} else if (proxy_type == 2) {
tox_options_set_proxy_type(opts, TOX_PROXY_TYPE_HTTP);
tox_options_set_proxy_host(opts, "127.0.0.1");
tox_options_set_proxy_port(opts, 8080);
}

Tox_Err_New error_new;
Tox *tox = tox_new(opts, &error_new);
tox_options_free(opts);

if (tox == nullptr) {
// It might fail, because some I/O happens in tox_new, and the fuzzer
// might do things that make that I/O fail.
return 0;
return;
}

assert(error_new == TOX_ERR_NEW_OK);

uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0};

const bool success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr);
assert(success);
const bool udp_success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr);
assert(udp_success);

const bool tcp_success = tox_add_tcp_relay(tox, "127.0.0.1", 12345, pub_key, nullptr);
assert(tcp_success);

tox_events_init(tox);

Expand All @@ -158,5 +169,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)

tox_dispatch_free(dispatch);
tox_kill(tox);
}

}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
Fuzz_Data input{data, size};
TestBootstrap(input);
return 0; // Non-zero return values are reserved for future use.
}
18 changes: 10 additions & 8 deletions testing/fuzzing/fuzz_support.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,9 @@ static constexpr Network_Funcs fuzz_network_funcs = {
/* .bind = */ [](void *obj, int sock, const Network_Addr *addr) { return 0; },
/* .listen = */ [](void *obj, int sock, int backlog) { return 0; },
/* .recvbuf = */
[](void *obj, int sock) {
// TODO(iphydf): Return something sensible here (from the fuzzer): number of
// bytes to be read from the socket.
return 0;
![](Fuzz_System *self, int sock) {
const size_t count = random_u16(self->rng.get());
return static_cast<int>(std::min(count, self->data.size));
},
/* .recv = */
![](Fuzz_System *self, int sock, uint8_t *buf, size_t len) {
Expand Down Expand Up @@ -107,10 +106,13 @@ static constexpr Random_Funcs fuzz_random_funcs = {
},
/* .random_uniform = */
![](Fuzz_System *self, uint32_t upper_bound) {
uint32_t randnum;
self->rng->funcs->random_bytes(
self, reinterpret_cast<uint8_t *>(&randnum), sizeof(randnum));
return randnum % upper_bound;
uint32_t randnum = 0;
if (upper_bound > 0) {
self->rng->funcs->random_bytes(
self, reinterpret_cast<uint8_t *>(&randnum), sizeof(randnum));
randnum %= upper_bound;
}
return randnum;
},
};

Expand Down
24 changes: 17 additions & 7 deletions toxcore/TCP_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C
char success[] = "200";
uint8_t data[16]; // draining works the best if the length is a power of 2

const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data) - 1, &tcp_conn->con.ip_port);
const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data) - 1,
&tcp_conn->con.ip_port);

if (ret == -1) {
return 0;
Expand All @@ -161,14 +162,19 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C

if (strstr((const char *)data, success) != nullptr) {
// drain all data
const uint16_t data_left = net_socket_data_recv_buffer(tcp_conn->con.ns, tcp_conn->con.sock);
uint16_t data_left = net_socket_data_recv_buffer(tcp_conn->con.ns, tcp_conn->con.sock);

if (data_left > 0) {
VLA(uint8_t, temp_data, data_left);
if (read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, temp_data, data_left, &tcp_conn->con.ip_port) == -1) {
while (data_left > 0) {
uint8_t temp_data[16];
const uint16_t temp_data_size = min_u16(data_left, sizeof(temp_data));

if (read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, temp_data, temp_data_size,
&tcp_conn->con.ip_port) == -1) {
LOGGER_ERROR(logger, "failed to drain TCP data (but ignoring failure)");
return 1;
}

data_left -= temp_data_size;
}

return 1;
Expand Down Expand Up @@ -812,12 +818,16 @@ static int handle_TCP_client_packet(const Logger *logger, TCP_Client_Connection
return handle_TCP_client_oob_recv(conn, data, length, userdata);

case TCP_PACKET_ONION_RESPONSE: {
conn->onion_callback(conn->onion_callback_object, data + 1, length - 1, userdata);
if (conn->onion_callback != nullptr) {
conn->onion_callback(conn->onion_callback_object, data + 1, length - 1, userdata);
}
return 0;
}

case TCP_PACKET_FORWARDING: {
conn->forwarded_response_callback(conn->forwarded_response_callback_object, data + 1, length - 1, userdata);
if (conn->forwarded_response_callback != nullptr) {
conn->forwarded_response_callback(conn->forwarded_response_callback_object, data + 1, length - 1, userdata);
}
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion toxcore/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ static uint32_t data_1(uint16_t buflen, const uint8_t *buffer)
{
uint32_t data = 0;

if (buflen > 7) {
if (buflen > 8) {
net_unpack_u32(buffer + 5, &data);
}

Expand Down

0 comments on commit 8ec6d68

Please sign in to comment.