test: Add more functionality to the bootstrap harness.

Ideally this would be able to reach some of the events, so we can write
code to respond to those events, but so far only the friend request
event actually happens.
This commit is contained in:
iphydf 2022-04-02 17:10:09 +00:00
parent e3fd8922a4
commit cb34fe12d1
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
13 changed files with 362 additions and 299 deletions

View File

@ -1 +1 @@
39a74721e1730757bdb96020acebe25bafb450a4298e4bc9556e3ad2d59260b1 /usr/local/bin/tox-bootstrapd
7c43e683316530c0e9c46df4e670465b887f2a0c0774ee1dc67e4b0e1ca20a35 /usr/local/bin/tox-bootstrapd

View File

@ -1,19 +1,18 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test")
cc_library(
name = "fuzz_adapter",
srcs = ["fuzz_adapter.c"],
hdrs = ["fuzz_adapter.h"],
visibility = ["//c-toxcore:__subpackages__"],
)
package(features = ["layering_check"])
cc_library(
name = "fuzz_support",
srcs = ["fuzz_support.cc"],
hdrs = ["fuzz_support.h"],
visibility = ["//c-toxcore:__subpackages__"],
deps = ["//c-toxcore/toxcore:tox"],
deps = [
"//c-toxcore/toxcore:crypto_core",
"//c-toxcore/toxcore:network",
"//c-toxcore/toxcore:tox",
],
)
cc_library(
@ -31,6 +30,9 @@ cc_fuzz_test(
deps = [
":fuzz_support",
"//c-toxcore/toxcore:tox",
"//c-toxcore/toxcore:tox_dispatch",
"//c-toxcore/toxcore:tox_events",
"//c-toxcore/toxcore:util",
],
)

View File

@ -2,7 +2,7 @@
target_compile_definitions(toxcore_static PUBLIC "FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION")
# Override network and random functions
add_library(fuzz_adapter fuzz_adapter.c fuzz_support.cc fuzz_support.h)
add_library(fuzz_support fuzz_support.cc fuzz_support.h)
set(LIBFUZZER_LINKER_FLAGS)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
@ -13,14 +13,14 @@ endif()
# Fuzzes the toxsave API
add_executable(toxsave_fuzzer toxsave_harness.cc)
target_link_libraries(toxsave_fuzzer toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS})
target_link_libraries(toxsave_fuzzer toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})
# Fuzzes the bootstrap process
add_executable(bootstrap_fuzzer bootstrap_harness.cc)
target_link_libraries(bootstrap_fuzzer toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS})
target_link_libraries(bootstrap_fuzzer toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})
add_executable(DHT_fuzz_test ../../toxcore/DHT_fuzz_test.cc)
target_link_libraries(DHT_fuzz_test toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS})
target_link_libraries(DHT_fuzz_test toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})
add_executable(tox_events_fuzz_test ../../toxcore/tox_events_fuzz_test.cc)
target_link_libraries(tox_events_fuzz_test toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS})
target_link_libraries(tox_events_fuzz_test toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS})

View File

@ -3,23 +3,124 @@
#include <memory>
#include "../../toxcore/tox.h"
#include "../../toxcore/tox_dispatch.h"
#include "../../toxcore/tox_events.h"
#include "../../toxcore/tox_private.h"
#include "fuzz_adapter.h"
#include "../../toxcore/tox_struct.h"
#include "../../toxcore/util.h"
#include "fuzz_support.h"
namespace {
void setup_callbacks(Tox_Dispatch *dispatch)
{
tox_events_callback_conference_connected(
dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_conference_connected(
dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_conference_invite(
dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_conference_message(
dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_conference_peer_list_changed(dispatch,
[](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_conference_peer_name(
dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_conference_title(
dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_file_chunk_request(
dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_file_recv(
dispatch, [](Tox *tox, const Tox_Event_File_Recv *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_file_recv_chunk(
dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_file_recv_control(
dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_connection_status(
dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_lossless_packet(
dispatch, [](Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_lossy_packet(
dispatch, [](Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_message(
dispatch, [](Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_name(
dispatch, [](Tox *tox, const Tox_Event_Friend_Name *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_read_receipt(
dispatch, [](Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_request(
dispatch, [](Tox *tox, const Tox_Event_Friend_Request *event, void *user_data) {
Tox_Err_Friend_Add err;
tox_friend_add_norequest(tox, tox_event_friend_request_get_public_key(event), &err);
assert(err == TOX_ERR_FRIEND_ADD_OK || err == TOX_ERR_FRIEND_ADD_OWN_KEY
|| err == TOX_ERR_FRIEND_ADD_ALREADY_SENT
|| err == TOX_ERR_FRIEND_ADD_BAD_CHECKSUM);
});
tox_events_callback_friend_status(
dispatch, [](Tox *tox, const Tox_Event_Friend_Status *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_status_message(
dispatch, [](Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_friend_typing(
dispatch, [](Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data) {
assert(event == nullptr);
});
tox_events_callback_self_connection_status(
dispatch, [](Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data) {
assert(event == nullptr);
});
}
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
network_adapter_init(data, size);
Fuzz_Data input{data, size};
uint64_t clock = 0;
auto sys = fuzz_system(clock);
assert(sys->mono_time_callback != nullptr);
assert(sys->mono_time_user_data != nullptr);
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.get());
tox_options_set_operating_system(opts, sys.sys.get());
Tox_Err_New error_new;
Tox *tox = tox_new(opts, &error_new);
@ -34,19 +135,24 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
const bool success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr);
assert(success);
/*
* The iteration count here is a magic value in the literal sense, too small
* and coverage will be bad, too big and fuzzing will not be efficient.
* NOTE: This should be fine tuned after gathering some experience.
*/
tox_events_init(tox);
for (uint32_t i = 0; i < 50; ++i) {
tox_iterate(tox, nullptr);
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
assert(dispatch != nullptr);
setup_callbacks(dispatch);
while (input.size > 0) {
Tox_Err_Events_Iterate error_iterate;
Tox_Events *events = tox_events_iterate(tox, true, &error_iterate);
assert(tox_events_equal(events, events));
tox_dispatch_invoke(dispatch, events, tox, nullptr);
tox_events_free(events);
// Move the clock forward a decent amount so all the time-based checks
// trigger more quickly.
clock += 200;
sys.clock += 200;
}
tox_dispatch_free(dispatch);
tox_kill(tox);
return 0; // Non-zero return values are reserved for future use.
}

View File

@ -1,89 +0,0 @@
#include "fuzz_adapter.h"
struct fuzz_buf {
/* Fuzz data buffer */
const uint8_t *cur;
const uint8_t *end;
};
static struct fuzz_buf data;
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
void network_adapter_init(const uint8_t *buf, size_t length)
{
data.cur = buf;
data.end = buf + length;
}
ssize_t fuzz_sendto(int sockfd, const void *buf, size_t len,
int flags, const struct sockaddr *addr,
socklen_t addrlen)
{
return len;
}
ssize_t fuzz_send(int sockfd, const void *buf, size_t len, int flags)
{
return len;
}
static ssize_t recv_common(void *buf, size_t buf_len)
{
if (data.cur + 2 >= data.end) {
return -1;
}
uint16_t fuzz_len = (data.cur[0] << 8) | data.cur[1];
data.cur += 2;
size_t available = data.end - data.cur;
size_t res = fuzz_len > available ? available : fuzz_len;
res = buf_len > res ? res : buf_len;
memcpy(buf, data.cur, res);
data.cur += res;
return res;
}
ssize_t fuzz_recvfrom(int sockfd, void *buf, size_t len,
int flags, struct sockaddr *src_addr,
socklen_t *addr_len)
{
if (src_addr && addr_len && (sizeof(struct sockaddr) <= *addr_len)) {
*src_addr = (struct sockaddr) {
0
};
// Dummy Addr
src_addr->sa_family = AF_INET;
// We want an AF_INET address with dummy values
struct sockaddr_in *addr_in = (struct sockaddr_in *)(void *)src_addr;
addr_in->sin_port = 12356;
addr_in->sin_addr.s_addr = INADDR_LOOPBACK + 1;
*addr_len = sizeof(struct sockaddr);
}
return recv_common(buf, len);
}
ssize_t fuzz_recv(int sockfd, void *buf, size_t len, int flags)
{
return recv_common(buf, len);
}
void fuzz_random_bytes(uint8_t *rnd, size_t length)
{
// Amount of data is limited
size_t available = data.end - data.cur;
size_t bytes_read = length > available ? available : length;
// Initialize everything to make MSAN and others happy
memset(rnd, 0, length);
memcpy(rnd, data.cur, bytes_read);
data.cur += bytes_read;
}

View File

@ -1,44 +0,0 @@
/* SPDX-License-Identifier: GPL-3.0-or-later
* Copyright © 2021 The TokTok team.
*/
#ifndef C_TOXCORE_TESTING_FUZZING_FUZZ_ADAPTER_H
#define C_TOXCORE_TESTING_FUZZING_FUZZ_ADAPTER_H
#include <stdint.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Init function for the fuzzing harness
* @param buf Begin of fuzz data
* @param length Length of buf
*/
void network_adapter_init(const uint8_t *buf, size_t length);
/* The following functions intercept calls to standard network functions for fuzzing purposes and return data from the fuzz buffer. */
ssize_t fuzz_sendto(int sockfd, const void *buf, size_t len,
int flags, const struct sockaddr *addr,
socklen_t addrlen);
ssize_t fuzz_send(int sockfd, const void *buf, size_t len, int flags);
ssize_t fuzz_recvfrom(int sockfd, void *buf, size_t len,
int flags, struct sockaddr *src_addr,
socklen_t *addr_len);
ssize_t fuzz_recv(int sockfd, void *buf, size_t len, int flags);
/* The following functions intercept generation of random data */
void fuzz_random_bytes(uint8_t *rnd, size_t length);
#ifdef __cplusplus
}
#endif
#endif // C_TOXCORE_TESTING_FUZZING_FUZZ_ADAPTER_H

View File

@ -4,18 +4,128 @@
#include "fuzz_support.h"
#include <arpa/inet.h>
#include <sys/socket.h>
#include <algorithm>
#include <cstring>
#include <memory>
#include "../../toxcore/crypto_core.h"
#include "../../toxcore/network.h"
#include "../../toxcore/tox_private.h"
std::unique_ptr<Tox_System> fuzz_system(uint64_t &clock)
// TODO(iphydf): Put this somewhere shared.
struct Network_Addr {
struct sockaddr_storage addr;
size_t size;
};
static int recv_common(Fuzz_Data &input, void *buf, size_t buf_len)
{
auto sys = std::make_unique<Tox_System>();
sys->mono_time_callback = [](void *user_data) { return *static_cast<uint64_t *>(user_data); };
sys->mono_time_user_data = &clock;
sys->rng = system_random(); // TODO(iphydf): Put fuzz_random here.
sys->ns = system_network(); // TODO(iphydf): Put fuzz_network here.
return sys;
if (input.size < 2) {
return -1;
}
const size_t fuzz_len = (input.data[0] << 8) | input.data[1];
input.data += 2;
input.size -= 2;
const size_t res = std::min(buf_len, std::min(fuzz_len, input.size));
memcpy(buf, input.data, res);
input.data += res;
input.size -= res;
return res;
}
static const Network_Funcs fuzz_network_funcs = {
.close = [](void *obj, int sock) { return 0; },
.accept = [](void *obj, int sock) { return 2; },
.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;
},
.recv =
[](void *obj, int sock, uint8_t *buf, size_t len) {
// Receive data from the fuzzer.
return recv_common(static_cast<Fuzz_System *>(obj)->data, buf, len);
},
.recvfrom =
[](void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) {
addr->addr = sockaddr_storage{};
// Dummy Addr
addr->addr.ss_family = AF_INET;
// We want an AF_INET address with dummy values
sockaddr_in *addr_in = reinterpret_cast<sockaddr_in *>(&addr->addr);
addr_in->sin_port = 12356;
addr_in->sin_addr.s_addr = INADDR_LOOPBACK + 1;
addr->size = sizeof(struct sockaddr);
return recv_common(static_cast<Fuzz_System *>(obj)->data, buf, len);
},
.send =
[](void *obj, int sock, const uint8_t *buf, size_t len) {
// Always succeed.
return static_cast<int>(len);
},
.sendto =
[](void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) {
// Always succeed.
return static_cast<int>(len);
},
.socket = [](void *obj, int domain, int type, int proto) { return 1; },
.socket_nonblock = [](void *obj, int sock, bool nonblock) { return 0; },
.getsockopt =
[](void *obj, int sock, int level, int optname, void *optval, size_t *optlen) {
memset(optval, 0, *optlen);
return 0;
},
.setsockopt = [](void *obj, int sock, int level, int optname, const void *optval,
size_t optlen) { return 0; },
};
static const Random_Funcs fuzz_random_funcs = {
.random_bytes =
[](void *obj, uint8_t *bytes, size_t length) {
Fuzz_System *sys = static_cast<Fuzz_System *>(obj);
// Amount of data is limited
const size_t available = sys->data.size;
const size_t bytes_read = std::min(length, available);
// Initialize everything to make MSAN and others happy
std::memset(bytes, 0, length);
std::memcpy(bytes, sys->data.data, bytes_read);
sys->data.data += bytes_read;
sys->data.size -= bytes_read;
},
.random_uniform =
[](void *obj, uint32_t upper_bound) {
Fuzz_System *sys = static_cast<Fuzz_System *>(obj);
uint32_t randnum;
sys->rng->funcs->random_bytes(
sys, reinterpret_cast<uint8_t *>(&randnum), sizeof(randnum));
return randnum % upper_bound;
},
};
Fuzz_System::Fuzz_System(Fuzz_Data &input)
: clock(0)
, data(input)
, sys(std::make_unique<Tox_System>())
, ns(std::make_unique<Network>(Network{&fuzz_network_funcs, this}))
, rng(std::make_unique<Random>(Random{&fuzz_random_funcs, this}))
{
sys->mono_time_callback
= [](void *user_data) { return static_cast<Fuzz_System *>(user_data)->clock; };
sys->mono_time_user_data = this;
sys->ns = ns.get();
sys->rng = rng.get();
}
Fuzz_System::~Fuzz_System() { }

View File

@ -97,6 +97,18 @@ void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&... args)
return fuzz_select_target(selector, input, std::forward<Args>(args)...);
}
std::unique_ptr<Tox_System> fuzz_system(uint64_t &clock);
struct Network;
struct Random;
struct Fuzz_System {
uint64_t clock;
Fuzz_Data &data;
std::unique_ptr<Tox_System> sys;
std::unique_ptr<Network> ns;
std::unique_ptr<Random> rng;
Fuzz_System(Fuzz_Data &input);
~Fuzz_System();
};
#endif // C_TOXCORE_TESTING_FUZZING_FUZZ_SUPPORT_H

View File

@ -6,8 +6,9 @@
#include "../../toxcore/tox_private.h"
#include "fuzz_support.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
namespace {
void TestSaveDataLoading(Fuzz_Data &input)
{
Tox_Err_Options_New error_options;
@ -16,19 +17,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
assert(tox_options != nullptr);
assert(error_options == TOX_ERR_OPTIONS_NEW_OK);
uint64_t clock = 0;
auto sys = fuzz_system(clock);
tox_options_set_operating_system(tox_options, sys.get());
const size_t savedata_size = input.size;
CONSUME_OR_RETURN(const uint8_t *savedata, input, savedata_size);
Fuzz_System sys(input);
tox_options_set_operating_system(tox_options, sys.sys.get());
// pass test data to Tox
tox_options_set_savedata_data(tox_options, data, size);
tox_options_set_savedata_data(tox_options, savedata, savedata_size);
tox_options_set_savedata_type(tox_options, TOX_SAVEDATA_TYPE_TOX_SAVE);
Tox *tox = tox_new(tox_options, nullptr);
tox_options_free(tox_options);
if (tox == nullptr) {
// Tox save was invalid, we're finished here
return 0;
return;
}
// verify that the file can be saved again
@ -36,5 +39,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
tox_get_savedata(tox, new_savedata.data());
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};
TestSaveDataLoading(input);
return 0; // Non-zero return values are reserved for future use.
}

View File

@ -64,7 +64,6 @@ cc_library(
visibility = ["//c-toxcore:__subpackages__"],
deps = [
":ccompat",
"//c-toxcore/testing/fuzzing:fuzz_adapter",
"@libsodium",
],
)
@ -136,7 +135,6 @@ cc_library(
],
deps = [
":ccompat",
"//c-toxcore/testing/fuzzing:fuzz_adapter",
"@pthread",
],
)
@ -160,6 +158,7 @@ cc_library(
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
"//c-toxcore/testing/fuzzing:__pkg__",
"//c-toxcore/toxav:__pkg__",
],
deps = [
@ -178,6 +177,7 @@ cc_library(
"//c-toxcore/auto_tests:__pkg__",
"//c-toxcore/other:__pkg__",
"//c-toxcore/other/bootstrap_daemon:__pkg__",
"//c-toxcore/testing/fuzzing:__pkg__",
"//c-toxcore/toxav:__pkg__",
],
deps = [
@ -186,7 +186,6 @@ cc_library(
":logger",
":mono_time",
":util",
"//c-toxcore/testing/fuzzing:fuzz_adapter",
"@libsodium",
"@psocket",
"@pthread",

View File

@ -12,8 +12,6 @@
#include "attributes.h"
/* No declarations here. */
//!TOKSTYLE-
// Variable length arrays.

View File

@ -40,12 +40,6 @@
#define ENC_SECRET_KEY_SIZE CRYPTO_SECRET_KEY_SIZE
#endif
//!TOKSTYLE-
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#include "../testing/fuzzing/fuzz_adapter.h"
#endif
//!TOKSTYLE+
static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES,
"CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES");
static_assert(CRYPTO_SECRET_KEY_SIZE == crypto_box_SECRETKEYBYTES,
@ -122,38 +116,38 @@ static void crypto_free(uint8_t *ptr, size_t bytes)
void crypto_memzero(void *data, size_t length)
{
#ifndef VANILLA_NACL
sodium_memzero(data, length);
#else
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL)
memset(data, 0, length);
#else
sodium_memzero(data, length);
#endif
}
bool crypto_memlock(void *data, size_t length)
{
#ifndef VANILLA_NACL
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL)
return false;
#else
if (sodium_mlock(data, length) != 0) {
return false;
}
return true;
#else
return false;
#endif
}
bool crypto_memunlock(void *data, size_t length)
{
#ifndef VANILLA_NACL
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL)
return false;
#else
if (sodium_munlock(data, length) != 0) {
return false;
}
return true;
#else
return false;
#endif
}
@ -169,18 +163,26 @@ bool public_key_eq(const uint8_t *pk1, const uint8_t *pk2)
bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2)
{
#ifndef VANILLA_NACL
return crypto_verify_64(cksum1, cksum2) == 0;
#else
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
// Hope that this is better for the fuzzer
return memcmp(cksum1, cksum2, CRYPTO_SHA512_SIZE) == 0;
#elif defined(VANILLA_NACL)
const int lo = crypto_verify_32(cksum1, cksum2) == 0 ? 1 : 0;
const int hi = crypto_verify_32(cksum1 + 8, cksum2 + 8) == 0 ? 1 : 0;
return (lo & hi) == 1;
#else
return crypto_verify_64(cksum1, cksum2) == 0;
#endif
}
bool crypto_sha256_eq(const uint8_t *cksum1, const uint8_t *cksum2)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// Hope that this is better for the fuzzer
return memcmp(cksum1, cksum2, CRYPTO_SHA256_SIZE) == 0;
#else
return crypto_verify_32(cksum1, cksum2) == 0;
#endif
}
uint8_t random_u08(const Random *rng)
@ -238,17 +240,19 @@ bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, u
bool public_key_valid(const uint8_t *public_key)
{
if (public_key[31] >= 128) { /* Last bit of key is always zero. */
return false;
}
return true;
/* Last bit of key is always zero. */
return public_key[31] < 128;
}
int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key,
uint8_t *shared_key)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
memcpy(shared_key, public_key, CRYPTO_SHARED_KEY_SIZE);
return 0;
#else
return crypto_box_beforenm(shared_key, public_key, secret_key);
#endif
}
int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce,
@ -450,11 +454,6 @@ void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key)
crypto_scalarmult_curve25519_base(public_key, secret_key);
}
void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length)
{
crypto_hash_sha256(hash, data, length);
}
void new_hmac_key(const Random *rng, uint8_t *key)
{
random_bytes(rng, key, CRYPTO_HMAC_KEY_SIZE);
@ -472,31 +471,42 @@ bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[
return crypto_auth_verify(auth, data, length, key) == 0;
}
void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
memset(hash, 0, CRYPTO_SHA256_SIZE);
memcpy(hash, data, length < CRYPTO_SHA256_SIZE ? length : CRYPTO_SHA256_SIZE);
#else
crypto_hash_sha256(hash, data, length);
#endif
}
void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
memset(hash, 0, CRYPTO_SHA512_SIZE);
memcpy(hash, data, length < CRYPTO_SHA512_SIZE ? length : CRYPTO_SHA512_SIZE);
#else
crypto_hash_sha512(hash, data, length);
#endif
}
non_null()
static void sys_random_bytes(void *obj, uint8_t *bytes, size_t length)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
fuzz_random_bytes(bytes, length);
#else
randombytes(bytes, length);
#endif
}
non_null()
static uint32_t sys_random_uniform(void *obj, uint32_t upper_bound)
{
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL)
#ifdef VANILLA_NACL
uint32_t randnum;
sys_random_bytes(obj, (uint8_t *)&randnum, sizeof(randnum));
return randnum % upper_bound;
#else
return randombytes_uniform(upper_bound);
#endif // VANILLA_NACL
#endif
}
static const Random_Funcs system_random_funcs = {
@ -508,6 +518,11 @@ static const Random system_random_obj = {&system_random_funcs};
const Random *system_random(void)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
return nullptr;
}
#endif
#ifndef VANILLA_NACL
// It is safe to call this function more than once and from different
// threads -- subsequent calls won't have any effects.
@ -515,7 +530,6 @@ const Random *system_random(void)
return nullptr;
}
#endif
return &system_random_obj;
}

View File

@ -97,12 +97,6 @@
#include "mono_time.h"
#include "util.h"
//!TOKSTYLE-
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#include "../testing/fuzzing/fuzz_adapter.h"
#endif
//!TOKSTYLE+
// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD
#if !defined(MSG_NOSIGNAL)
#define MSG_NOSIGNAL 0
@ -127,12 +121,10 @@ static bool should_ignore_recv_error(int err)
return err == EWOULDBLOCK;
}
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
static bool should_ignore_connect_error(int err)
{
return err == EWOULDBLOCK || err == EINPROGRESS;
}
#endif
non_null()
static const char *inet_ntop4(const struct in_addr *addr, char *buf, size_t bufsize)
@ -488,54 +480,34 @@ struct Network_Addr {
non_null()
static int sys_close(void *obj, int sock)
{
#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
return 0;
#elif defined(OS_WIN32)
#if defined(OS_WIN32)
return closesocket(sock);
#else // !OS_WIN32
return close(sock);
#endif // FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
#endif
}
non_null()
static int sys_accept(void *obj, int sock)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 2;
#else
return accept(sock, nullptr, nullptr);
#endif
}
non_null()
static int sys_bind(void *obj, int sock, const Network_Addr *addr)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 0;
#else
return bind(sock, (const struct sockaddr *)&addr->addr, addr->size);
#endif
}
non_null()
static int sys_listen(void *obj, int sock, int backlog)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 0;
#else
return listen(sock, backlog);
#endif
}
non_null()
static int sys_recvbuf(void *obj, int sock)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
// TODO(iphydf): Return something sensible here (from the fuzzer): number of
// bytes to be read from the socket.
return 0;
#else
#ifdef OS_WIN32
u_long count = 0;
ioctlsocket(sock, FIONREAD, &count);
@ -545,100 +517,63 @@ static int sys_recvbuf(void *obj, int sock)
#endif
return count;
#endif
}
non_null()
static int sys_recv(void *obj, int sock, uint8_t *buf, size_t len)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return fuzz_recv(sock, (char *)buf, len, MSG_NOSIGNAL);
#else
return recv(sock, (char *)buf, len, MSG_NOSIGNAL);
#endif
}
non_null()
static int sys_send(void *obj, int sock, const uint8_t *buf, size_t len)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return fuzz_send(sock, (const char *)buf, len, MSG_NOSIGNAL);
#else
return send(sock, (const char *)buf, len, MSG_NOSIGNAL);
#endif
}
non_null()
static int sys_sendto(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) {
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return fuzz_sendto(sock, (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size);
#else
return sendto(sock, (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size);
#endif
}
non_null()
static int sys_recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) {
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
socklen_t size = addr->size;
const int ret = fuzz_recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size);
addr->size = size;
return ret;
#else
socklen_t size = addr->size;
const int ret = recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size);
addr->size = size;
return ret;
#endif
}
non_null()
static int sys_socket(void *obj, int domain, int type, int proto)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 1;
#else
return (int)socket(domain, type, proto);
#endif
}
non_null()
static int sys_socket_nonblock(void *obj, int sock, bool nonblock)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 0;
#else
#ifdef OS_WIN32
u_long mode = nonblock ? 1 : 0;
return ioctlsocket(sock, FIONBIO, &mode);
#else
return fcntl(sock, F_SETFL, O_NONBLOCK, nonblock ? 1 : 0);
#endif /* OS_WIN32 */
#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
}
non_null()
static int sys_getsockopt(void *obj, int sock, int level, int optname, void *optval, size_t *optlen)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
memset(optval, 0, *optlen);
return 0;
#else
socklen_t len = *optlen;
const int ret = getsockopt(sock, level, optname, optval, &len);
*optlen = len;
return ret;
#endif
}
non_null()
static int sys_setsockopt(void *obj, int sock, int level, int optname, const void *optval, size_t optlen)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 0;
#else
return setsockopt(sock, level, optname, optval, optlen);
#endif
}
static const Network_Funcs system_network_funcs = {
@ -660,6 +595,11 @@ static const Network system_network_obj = {&system_network_funcs};
const Network *system_network(void)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
if ((true)) {
return nullptr;
}
#endif
#ifdef OS_WIN32
WSADATA wsaData;
@ -1528,11 +1468,9 @@ bool addr_parse_ip(const char *address, IP *to)
return false;
}
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/** addr_resolve return values */
#define TOX_ADDR_RESOLVE_INET 1
#define TOX_ADDR_RESOLVE_INET6 2
#endif
/**
* Uses getaddrinfo to resolve an address into an IP address.
@ -1555,8 +1493,10 @@ non_null(1, 2, 3) nullable(4)
static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extra)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return 0;
#else
if ((true)) {
return 0;
}
#endif
if (address == nullptr || to == nullptr) {
return 0;
@ -1641,7 +1581,6 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr
freeaddrinfo(server);
return result;
#endif
}
bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra)
@ -1682,8 +1621,11 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port)
}
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
return addrsize != 0;
#else
if ((true)) {
return true;
}
#endif
Ip_Ntoa ip_str;
LOGGER_DEBUG(log, "connecting socket %d to %s:%d",
(int)sock.sock, net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port));
@ -1703,20 +1645,22 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port)
}
return true;
#endif
}
int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
{
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
*res = (IP_Port *)calloc(1, sizeof(IP_Port));
assert(*res != nullptr);
IP_Port *ip_port = *res;
ip_port->ip.ip.v4.uint32 = 0x7F000003; // 127.0.0.3
ip_port->ip.family = *make_tox_family(AF_INET);
if ((true)) {
*res = (IP_Port *)calloc(1, sizeof(IP_Port));
assert(*res != nullptr);
IP_Port *ip_port = *res;
ip_port->ip.ip.v4.uint32 = 0x7F000003; // 127.0.0.3
ip_port->ip.family = *make_tox_family(AF_INET);
return 1;
}
#endif
return 1;
#else
// Try parsing as IP address first.
IP_Port parsed = {{{0}}};
@ -1805,7 +1749,6 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type)
freeaddrinfo(infos);
return count;
#endif
}
void net_freeipport(IP_Port *ip_ports)