From a549807df70c137ca9138269334f11c474f286c7 Mon Sep 17 00:00:00 2001 From: iphydf Date: Wed, 23 Aug 2023 10:26:11 +0000 Subject: [PATCH] refactor: Add `mem` module to allow tests to override allocators. This will allow us to do more interesting things with memory allocation within toxcore, and allow fuzzers to explore various allocation failure paths. --- .github/scripts/coverage-linux | 6 +- CMakeLists.txt | 3 + auto_tests/TCP_test.c | 99 +++++++++------ auto_tests/announce_test.c | 13 +- auto_tests/forwarding_test.c | 34 +++--- auto_tests/onion_test.c | 67 +++++----- auto_tests/tox_dispatch_test.c | 22 ++-- azure-pipelines.yml | 2 +- codecov.yml | 4 + other/DHT_bootstrap.c | 14 ++- .../docker/tox-bootstrapd.sha256 | 2 +- other/bootstrap_daemon/src/tox-bootstrapd.c | 44 +++---- other/docker/coverage/Dockerfile | 7 +- other/proxy/go.mod | 4 +- other/proxy/go.sum | 2 + testing/Messenger_test.c | 5 +- testing/fuzzing/BUILD.bazel | 4 + testing/fuzzing/bootstrap_harness.cc | 2 +- testing/fuzzing/e2e_fuzz_test.cc | 4 +- testing/fuzzing/fuzz_support.cc | 46 +++++++ testing/fuzzing/fuzz_support.h | 19 +++ testing/fuzzing/fuzz_tox.h | 5 +- testing/fuzzing/protodump.cc | 4 +- testing/fuzzing/protodump_reduce.cc | 2 +- toxav/groupav.c | 2 +- toxav/toxav.c | 4 +- toxcore/BUILD.bazel | 37 +++++- toxcore/DHT.c | 79 ++++++------ toxcore/DHT.h | 7 +- toxcore/DHT_test.cc | 12 +- toxcore/Makefile.inc | 2 + toxcore/Messenger.c | 70 ++++++----- toxcore/Messenger.h | 4 +- toxcore/TCP_client.c | 53 +++++--- toxcore/TCP_client.h | 6 +- toxcore/TCP_common.c | 30 ++--- toxcore/TCP_common.h | 11 +- toxcore/TCP_connection.c | 53 ++++---- toxcore/TCP_connection.h | 5 +- toxcore/TCP_server.c | 39 +++--- toxcore/TCP_server.h | 4 +- toxcore/announce.c | 10 +- toxcore/announce.h | 3 +- toxcore/forwarding_fuzz_test.cc | 8 +- toxcore/group_announce_fuzz_test.cc | 6 +- toxcore/group_announce_test.cc | 5 +- toxcore/group_chats.c | 5 +- toxcore/group_common.h | 1 + toxcore/group_moderation.c | 4 +- toxcore/group_moderation.h | 1 + toxcore/group_moderation_fuzz_test.cc | 2 +- toxcore/group_moderation_test.cc | 36 +++--- toxcore/mem.c | 88 ++++++++++++++ toxcore/mem.h | 86 +++++++++++++ toxcore/mem_test.cc | 40 ++++++ toxcore/mono_time.c | 22 ++-- toxcore/mono_time.h | 9 +- toxcore/mono_time_test.cc | 15 ++- toxcore/net_crypto.c | 89 +++++++------- toxcore/net_crypto.h | 3 +- toxcore/network.c | 35 +++--- toxcore/network.h | 15 +-- toxcore/onion.c | 13 +- toxcore/onion.h | 3 +- toxcore/onion_announce.c | 48 ++++---- toxcore/onion_announce.h | 2 +- toxcore/onion_client.c | 30 +++-- toxcore/onion_client.h | 2 +- toxcore/ping.c | 12 +- toxcore/ping.h | 6 +- toxcore/ping_array.c | 18 +-- toxcore/ping_array.h | 4 +- toxcore/ping_array_test.cc | 67 ++++++---- toxcore/shared_key_cache.c | 27 +++-- toxcore/shared_key_cache.h | 5 +- toxcore/tox.c | 114 +++++++++--------- toxcore/tox.h | 6 +- toxcore/tox_events.c | 24 ++-- toxcore/tox_events.h | 4 +- toxcore/tox_events_fuzz_test.cc | 26 +++- toxcore/tox_events_test.cc | 21 ++-- toxcore/tox_private.c | 8 +- toxcore/tox_private.h | 1 + toxcore/tox_struct.h | 4 +- toxcore/util.c | 6 +- toxcore/util.h | 5 +- 86 files changed, 1148 insertions(+), 623 deletions(-) create mode 100644 toxcore/mem.c create mode 100644 toxcore/mem.h create mode 100644 toxcore/mem_test.cc diff --git a/.github/scripts/coverage-linux b/.github/scripts/coverage-linux index 35a1e75924..4e73dae58e 100755 --- a/.github/scripts/coverage-linux +++ b/.github/scripts/coverage-linux @@ -9,7 +9,7 @@ sudo apt-get install -y --no-install-recommends \ libopus-dev \ libsodium-dev \ libvpx-dev \ - llvm-11 \ + llvm-14 \ ninja-build git clone --depth=1 https://github.com/ralight/mallocfail /tmp/mallocfail cd /tmp/mallocfail # pushd @@ -21,7 +21,7 @@ export CC=clang export CXX=clang++ sudo install other/docker/coverage/run_mallocfail /usr/local/bin/run_mallocfail -(cd other/proxy && go build) +(cd other/proxy && go get && go build) other/proxy/proxy & . ".github/scripts/flags-coverage.sh" @@ -58,4 +58,4 @@ cd - # popd # --exclude testing \ # --gcov-options '\-lp' -bash <(curl -s https://codecov.io/bash) -x "llvm-cov-11 gcov" +bash <(curl -s https://codecov.io/bash) -x "llvm-cov-14 gcov" diff --git a/CMakeLists.txt b/CMakeLists.txt index f6228e4eb8..d3cabf06c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,6 +268,8 @@ set(toxcore_SOURCES toxcore/logger.h toxcore/Messenger.c toxcore/Messenger.h + toxcore/mem.c + toxcore/mem.h toxcore/mono_time.c toxcore/mono_time.h toxcore/net_crypto.c @@ -434,6 +436,7 @@ unit_test(toxcore bin_pack) unit_test(toxcore crypto_core) unit_test(toxcore group_announce) unit_test(toxcore group_moderation) +unit_test(toxcore mem) unit_test(toxcore mono_time) unit_test(toxcore ping_array) unit_test(toxcore tox) diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 33bbe0e22c..d5455cf0e8 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -45,9 +45,14 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643}; static void test_basic(void) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); + const Network *ns = system_network(); + ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); Logger *logger = logger_new(); logger_callback_log(logger, print_debug_logger, nullptr, nullptr); @@ -55,8 +60,7 @@ static void test_basic(void) uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); - const Network *ns = system_network(); - TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); + TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind a TCP relay server to all %d attempted ports.", NUM_PORTS); @@ -70,7 +74,7 @@ static void test_basic(void) for (uint8_t i = 0; i < NUM_PORTS; i++) { sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); localhost.port = net_htons(ports[i]); - bool ret = net_connect(logger, sock, &localhost); + bool ret = net_connect(mem, logger, sock, &localhost); ck_assert_msg(ret, "Failed to connect to created TCP relay server on port %d (%d).", ports[i], errno); // Leave open one connection for the next test. @@ -184,30 +188,32 @@ static void test_basic(void) kill_TCP_server(tcp_s); logger_kill(logger); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } struct sec_TCP_con { Socket sock; const Network *ns; + const Memory *mem; uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t recv_nonce[CRYPTO_NONCE_SIZE]; uint8_t sent_nonce[CRYPTO_NONCE_SIZE]; uint8_t shared_key[CRYPTO_SHARED_KEY_SIZE]; }; -static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time) +static struct sec_TCP_con *new_TCP_con(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, TCP_Server *tcp_s, Mono_Time *mono_time) { struct sec_TCP_con *sec_c = (struct sec_TCP_con *)malloc(sizeof(struct sec_TCP_con)); ck_assert(sec_c != nullptr); sec_c->ns = ns; + sec_c->mem = mem; Socket sock = net_socket(ns, net_family_ipv6(), TOX_SOCK_STREAM, TOX_PROTO_TCP); IP_Port localhost; localhost.ip = get_loopback(); localhost.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); - bool ok = net_connect(logger, sock, &localhost); + bool ok = net_connect(mem, logger, sock, &localhost); ck_assert_msg(ok, "Failed to connect to the test TCP relay server."); uint8_t f_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -297,22 +303,26 @@ static int read_packet_sec_TCP(const Logger *logger, struct sec_TCP_con *con, ui static void test_some(void) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); - Logger *logger = logger_new(); const Network *ns = system_network(); + ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Logger *logger = logger_new(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); - TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); + TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); ck_assert_msg(tcp_s != nullptr, "Failed to create TCP relay server"); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind to all ports."); - struct sec_TCP_con *con1 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); - struct sec_TCP_con *con2 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); - struct sec_TCP_con *con3 = new_TCP_con(logger, rng, ns, tcp_s, mono_time); + struct sec_TCP_con *con1 = new_TCP_con(logger, mem, rng, ns, tcp_s, mono_time); + struct sec_TCP_con *con2 = new_TCP_con(logger, mem, rng, ns, tcp_s, mono_time); + struct sec_TCP_con *con3 = new_TCP_con(logger, mem, rng, ns, tcp_s, mono_time); uint8_t requ_p[1 + CRYPTO_PUBLIC_KEY_SIZE]; requ_p[0] = TCP_PACKET_ROUTING_REQUEST; @@ -402,7 +412,7 @@ static void test_some(void) kill_TCP_con(con3); logger_kill(logger); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } static int response_callback_good; @@ -488,16 +498,20 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint static void test_client(void) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); + const Network *ns = system_network(); + ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + Logger *logger = logger_new(); + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); - const Network *ns = system_network(); - TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); + TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); ck_assert_msg(tcp_s != nullptr, "Failed to create a TCP relay server."); ck_assert_msg(tcp_server_listen_count(tcp_s) == NUM_PORTS, "Failed to bind the relay server to all ports."); @@ -509,8 +523,7 @@ static void test_client(void) ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); - TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, - f_secret_key, nullptr); + TCP_Client_Connection *conn = new_TCP_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); do_TCP_connection(logger, mono_time, conn, nullptr); c_sleep(50); @@ -544,7 +557,7 @@ static void test_client(void) uint8_t f2_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, f2_public_key, f2_secret_key); ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); - TCP_Client_Connection *conn2 = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, + TCP_Client_Connection *conn2 = new_TCP_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key, f2_secret_key, nullptr); // The client should call this function (defined earlier) during the routing process. @@ -613,17 +626,21 @@ static void test_client(void) kill_TCP_connection(conn2); logger_kill(logger); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } // Test how the client handles servers that don't respond. static void test_client_invalid(void) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); - Logger *logger = logger_new(); const Network *ns = system_network(); + ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Logger *logger = logger_new(); uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; @@ -636,7 +653,7 @@ static void test_client_invalid(void) ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]); ip_port_tcp_s.ip = get_loopback(); - TCP_Client_Connection *conn = new_TCP_connection(logger, mono_time, rng, ns, &ip_port_tcp_s, + TCP_Client_Connection *conn = new_TCP_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr); // Run the client's main loop but not the server. @@ -663,7 +680,7 @@ static void test_client_invalid(void) kill_TCP_connection(conn); logger_kill(logger); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } #include "../toxcore/TCP_connection.h" @@ -694,27 +711,31 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t static void test_tcp_connection(void) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); - Logger *logger = logger_new(); const Random *rng = system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); + ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Logger *logger = logger_new(); tcp_data_callback_called = 0; uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); - TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); + TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); TCP_Proxy_Info proxy_info; proxy_info.proxy_type = TCP_PROXY_NONE; crypto_new_keypair(rng, self_public_key, self_secret_key); - TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); + TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); crypto_new_keypair(rng, self_public_key, self_secret_key); - TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); + TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); IP_Port ip_port_tcp_s; @@ -777,7 +798,7 @@ static void test_tcp_connection(void) kill_tcp_connections(tc_2); logger_kill(logger); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } static bool tcp_oobdata_callback_called; @@ -803,11 +824,15 @@ static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigne static void test_tcp_connection2(void) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); - Logger *logger = logger_new(); const Random *rng = system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); + ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Logger *logger = logger_new(); tcp_oobdata_callback_called = 0; tcp_data_callback_called = 0; @@ -815,17 +840,17 @@ static void test_tcp_connection2(void) uint8_t self_public_key[CRYPTO_PUBLIC_KEY_SIZE]; uint8_t self_secret_key[CRYPTO_SECRET_KEY_SIZE]; crypto_new_keypair(rng, self_public_key, self_secret_key); - TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); + TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, USE_IPV6, NUM_PORTS, ports, self_secret_key, nullptr, nullptr); ck_assert_msg(pk_equal(tcp_server_public_key(tcp_s), self_public_key), "Wrong public key"); TCP_Proxy_Info proxy_info; proxy_info.proxy_type = TCP_PROXY_NONE; crypto_new_keypair(rng, self_public_key, self_secret_key); - TCP_Connections *tc_1 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); + TCP_Connections *tc_1 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_1), self_public_key), "Wrong public key"); crypto_new_keypair(rng, self_public_key, self_secret_key); - TCP_Connections *tc_2 = new_tcp_connections(logger, rng, ns, mono_time, self_secret_key, &proxy_info); + TCP_Connections *tc_2 = new_tcp_connections(logger, mem, rng, ns, mono_time, self_secret_key, &proxy_info); ck_assert_msg(pk_equal(tcp_connections_public_key(tc_2), self_public_key), "Wrong public key"); IP_Port ip_port_tcp_s; @@ -881,7 +906,7 @@ static void test_tcp_connection2(void) kill_tcp_connections(tc_2); logger_kill(logger); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } static void TCP_suite(void) diff --git a/auto_tests/announce_test.c b/auto_tests/announce_test.c index c31d5ca75d..f0929c757c 100644 --- a/auto_tests/announce_test.c +++ b/auto_tests/announce_test.c @@ -54,14 +54,17 @@ static void test_store_data(void) ck_assert(rng != nullptr); const Network *ns = system_network(); ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + Logger *log = logger_new(); ck_assert(log != nullptr); logger_callback_log(log, print_debug_logger, nullptr, nullptr); - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); - Networking_Core *net = new_networking_no_udp(log, ns); - DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true); + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Networking_Core *net = new_networking_no_udp(log, mem, ns); + DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true); Forwarding *forwarding = new_forwarding(log, rng, mono_time, dht); - Announcements *announce = new_announcements(log, rng, mono_time, forwarding); + Announcements *announce = new_announcements(log, mem, rng, mono_time, forwarding); ck_assert(announce != nullptr); /* Just to prevent CI from complaining that set_synch_offset is unused: */ @@ -103,7 +106,7 @@ static void test_store_data(void) kill_forwarding(forwarding); kill_dht(dht); kill_networking(net); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); logger_kill(log); } diff --git a/auto_tests/forwarding_test.c b/auto_tests/forwarding_test.c index bc912fb053..f9c82784f2 100644 --- a/auto_tests/forwarding_test.c +++ b/auto_tests/forwarding_test.c @@ -102,56 +102,58 @@ typedef struct Forwarding_Subtox { Announcements *announce; } Forwarding_Subtox; -static Forwarding_Subtox *new_forwarding_subtox(bool no_udp, uint32_t *index, uint16_t port) +static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port) { + const Random *rng = system_random(); + ck_assert(rng != nullptr); + const Network *ns = system_network(); + ck_assert(ns != nullptr); + Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox)); ck_assert(subtox != nullptr); subtox->log = logger_new(); ck_assert(subtox->log != nullptr); logger_callback_log(subtox->log, print_debug_logger, nullptr, index); - subtox->mono_time = mono_time_new(nullptr, nullptr); - - const Random *rng= system_random(); - ck_assert(rng != nullptr); - const Network *ns = system_network(); - ck_assert(ns != nullptr); + subtox->mono_time = mono_time_new(mem, nullptr, nullptr); if (no_udp) { - subtox->net = new_networking_no_udp(subtox->log, ns); + subtox->net = new_networking_no_udp(subtox->log, mem, ns); } else { const IP ip = get_loopback(); - subtox->net = new_networking_ex(subtox->log, ns, &ip, port, port, nullptr); + subtox->net = new_networking_ex(subtox->log, mem, ns, &ip, port, port, nullptr); } - subtox->dht = new_dht(subtox->log, rng, ns, subtox->mono_time, subtox->net, true, true); + subtox->dht = new_dht(subtox->log, mem, rng, ns, subtox->mono_time, subtox->net, true, true); const TCP_Proxy_Info inf = {{{{0}}}}; - subtox->c = new_net_crypto(subtox->log, rng, ns, subtox->mono_time, subtox->dht, &inf); + subtox->c = new_net_crypto(subtox->log, mem, rng, ns, subtox->mono_time, subtox->dht, &inf); subtox->forwarding = new_forwarding(subtox->log, rng, subtox->mono_time, subtox->dht); ck_assert(subtox->forwarding != nullptr); - subtox->announce = new_announcements(subtox->log, rng, subtox->mono_time, subtox->forwarding); + subtox->announce = new_announcements(subtox->log, mem, rng, subtox->mono_time, subtox->forwarding); ck_assert(subtox->announce != nullptr); return subtox; } -static void kill_forwarding_subtox(Forwarding_Subtox *subtox) +static void kill_forwarding_subtox(const Memory *mem, Forwarding_Subtox *subtox) { kill_announcements(subtox->announce); kill_forwarding(subtox->forwarding); kill_net_crypto(subtox->c); kill_dht(subtox->dht); kill_networking(subtox->net); - mono_time_free(subtox->mono_time); + mono_time_free(mem, subtox->mono_time); logger_kill(subtox->log); free(subtox); } static void test_forwarding(void) { + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); const Random *rng = system_random(); ck_assert(rng != nullptr); const Network *ns = system_network(); @@ -165,7 +167,7 @@ static void test_forwarding(void) for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { index[i] = i + 1; - subtoxes[i] = new_forwarding_subtox(i < NUM_FORWARDER_TCP, &index[i], FORWARDING_BASE_PORT + i); + subtoxes[i] = new_forwarding_subtox(mem, i < NUM_FORWARDER_TCP, &index[i], FORWARDING_BASE_PORT + i); test_data[i].net = subtoxes[i]->net; test_data[i].send_back = 0; @@ -317,7 +319,7 @@ static void test_forwarding(void) for (uint32_t i = 0; i < NUM_FORWARDER; ++i) { - kill_forwarding_subtox(subtoxes[i]); + kill_forwarding_subtox(mem, subtoxes[i]); } tox_kill(relay); diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 02a15b2247..282b99637e 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -215,29 +215,32 @@ static void send_onion_packet(const Networking_Core *net, const Random *rng, con /** Initialize networking. * Added for reverse compatibility with old new_networking calls. */ -static Networking_Core *new_networking(const Logger *log, const Network *ns, const IP *ip, uint16_t port) +static Networking_Core *new_networking(const Logger *log, const Memory *mem, const Network *ns, const IP *ip, uint16_t port) { - return new_networking_ex(log, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr); + return new_networking_ex(log, mem, ns, ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), nullptr); } static void test_basic(void) { uint32_t index[] = { 1, 2, 3 }; const Network *ns = system_network(); + ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); + const Random *rng = system_random(); + ck_assert(rng != nullptr); Logger *log1 = logger_new(); logger_callback_log(log1, print_debug_logger, nullptr, &index[0]); Logger *log2 = logger_new(); logger_callback_log(log2, print_debug_logger, nullptr, &index[1]); - const Random *rng = system_random(); - ck_assert(rng != nullptr); - Mono_Time *mono_time1 = mono_time_new(nullptr, nullptr); - Mono_Time *mono_time2 = mono_time_new(nullptr, nullptr); + Mono_Time *mono_time1 = mono_time_new(mem, nullptr, nullptr); + Mono_Time *mono_time2 = mono_time_new(mem, nullptr, nullptr); IP ip = get_loopback(); - Onion *onion1 = new_onion(log1, mono_time1, rng, new_dht(log1, rng, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false)); - Onion *onion2 = new_onion(log2, mono_time2, rng, new_dht(log2, rng, ns, mono_time2, new_networking(log2, ns, &ip, 36568), true, false)); + Onion *onion1 = new_onion(log1, mem, mono_time1, rng, new_dht(log1, mem, rng, ns, mono_time1, new_networking(log1, mem, ns, &ip, 36567), true, false)); + Onion *onion2 = new_onion(log2, mem, mono_time2, rng, new_dht(log2, mem, rng, ns, mono_time2, new_networking(log2, mem, ns, &ip, 36568), true, false)); ck_assert_msg((onion1 != nullptr) && (onion2 != nullptr), "Onion failed initializing."); networking_registerhandler(onion2->net, NET_PACKET_ANNOUNCE_REQUEST, &handle_test_1, onion2); @@ -280,8 +283,8 @@ static void test_basic(void) do_onion(mono_time2, onion2); } while (handled_test_2 == 0); - Onion_Announce *onion1_a = new_onion_announce(log1, rng, mono_time1, onion1->dht); - Onion_Announce *onion2_a = new_onion_announce(log2, rng, mono_time2, onion2->dht); + Onion_Announce *onion1_a = new_onion_announce(log1, mem, rng, mono_time1, onion1->dht); + Onion_Announce *onion2_a = new_onion_announce(log2, mem, rng, mono_time2, onion2->dht); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1); networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1); ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing."); @@ -331,9 +334,9 @@ static void test_basic(void) Logger *log3 = logger_new(); logger_callback_log(log3, print_debug_logger, nullptr, &index[2]); - Mono_Time *mono_time3 = mono_time_new(nullptr, nullptr); + Mono_Time *mono_time3 = mono_time_new(mem, nullptr, nullptr); - Onion *onion3 = new_onion(log3, mono_time3, rng, new_dht(log3, rng, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false)); + Onion *onion3 = new_onion(log3, mem, mono_time3, rng, new_dht(log3, mem, rng, ns, mono_time3, new_networking(log3, mem, ns, &ip, 36569), true, false)); ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); random_nonce(rng, nonce); @@ -363,7 +366,7 @@ static void test_basic(void) kill_onion(onion); kill_dht(dht); kill_networking(net); - mono_time_free(mono_time3); + mono_time_free(mem, mono_time3); logger_kill(log3); } @@ -375,7 +378,7 @@ static void test_basic(void) kill_onion(onion); kill_dht(dht); kill_networking(net); - mono_time_free(mono_time2); + mono_time_free(mem, mono_time2); logger_kill(log2); } @@ -387,7 +390,7 @@ static void test_basic(void) kill_onion(onion); kill_dht(dht); kill_networking(net); - mono_time_free(mono_time1); + mono_time_free(mem, mono_time1); logger_kill(log1); } } @@ -400,7 +403,7 @@ typedef struct { Onion_Client *onion_c; } Onions; -static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) +static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, uint32_t *index) { IP ip = get_loopback(); ip.ip.v6.uint8[15] = 1; @@ -420,7 +423,7 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) logger_callback_log(on->log, print_debug_logger, nullptr, index); - on->mono_time = mono_time_new(nullptr, nullptr); + on->mono_time = mono_time_new(mem, nullptr, nullptr); if (!on->mono_time) { logger_kill(on->log); @@ -428,57 +431,57 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) return nullptr; } - Networking_Core *net = new_networking(on->log, ns, &ip, port); + Networking_Core *net = new_networking(on->log, mem, ns, &ip, port); if (!net) { - mono_time_free(on->mono_time); + mono_time_free(mem, on->mono_time); logger_kill(on->log); free(on); return nullptr; } - DHT *dht = new_dht(on->log, rng, ns, on->mono_time, net, true, false); + DHT *dht = new_dht(on->log, mem, rng, ns, on->mono_time, net, true, false); if (!dht) { kill_networking(net); - mono_time_free(on->mono_time); + mono_time_free(mem, on->mono_time); logger_kill(on->log); free(on); return nullptr; } - on->onion = new_onion(on->log, on->mono_time, rng, dht); + on->onion = new_onion(on->log, mem, on->mono_time, rng, dht); if (!on->onion) { kill_dht(dht); kill_networking(net); - mono_time_free(on->mono_time); + mono_time_free(mem, on->mono_time); logger_kill(on->log); free(on); return nullptr; } - on->onion_a = new_onion_announce(on->log, rng, on->mono_time, dht); + on->onion_a = new_onion_announce(on->log, mem, rng, on->mono_time, dht); if (!on->onion_a) { kill_onion(on->onion); kill_dht(dht); kill_networking(net); - mono_time_free(on->mono_time); + mono_time_free(mem, on->mono_time); logger_kill(on->log); free(on); return nullptr; } TCP_Proxy_Info inf = {{{{0}}}}; - on->onion_c = new_onion_client(on->log, rng, on->mono_time, new_net_crypto(on->log, rng, ns, on->mono_time, dht, &inf)); + on->onion_c = new_onion_client(on->log, mem, rng, on->mono_time, new_net_crypto(on->log, mem, rng, ns, on->mono_time, dht, &inf)); if (!on->onion_c) { kill_onion_announce(on->onion_a); kill_onion(on->onion); kill_dht(dht); kill_networking(net); - mono_time_free(on->mono_time); + mono_time_free(mem, on->mono_time); logger_kill(on->log); free(on); return nullptr; @@ -496,7 +499,7 @@ static void do_onions(Onions *on) do_onion_client(on->onion_c); } -static void kill_onions(Onions *on) +static void kill_onions(const Memory *mem, Onions *on) { Networking_Core *net = dht_get_net(on->onion->dht); DHT *dht = on->onion->dht; @@ -507,7 +510,7 @@ static void kill_onions(Onions *on) kill_net_crypto(c); kill_dht(dht); kill_networking(net); - mono_time_free(on->mono_time); + mono_time_free(mem, on->mono_time); logger_kill(on->log); free(on); } @@ -576,10 +579,12 @@ static void test_announce(void) Onions *onions[NUM_ONIONS]; const Random *rng = system_random(); ck_assert(rng != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); for (i = 0; i < NUM_ONIONS; ++i) { index[i] = i + 1; - onions[i] = new_onions(rng, i + 36655, &index[i]); + onions[i] = new_onions(mem, rng, i + 36655, &index[i]); ck_assert_msg(onions[i] != nullptr, "Failed to create onions. %u", i); } @@ -653,7 +658,7 @@ static void test_announce(void) ck_assert_msg(ip_port.port == net_port(onions[NUM_FIRST]->onion->net), "Port in returned ip not correct."); for (i = 0; i < NUM_ONIONS; ++i) { - kill_onions(onions[i]); + kill_onions(mem, onions[i]); } } diff --git a/auto_tests/tox_dispatch_test.c b/auto_tests/tox_dispatch_test.c index 3b2e991110..209e13788f 100644 --- a/auto_tests/tox_dispatch_test.c +++ b/auto_tests/tox_dispatch_test.c @@ -43,7 +43,7 @@ static void dump_events(const char *path, const Tox_Events *events) } } -static void print_events(Tox_Events *events) +static void print_events(const Tox_System *sys, Tox_Events *events) { const uint32_t size = tox_events_bytes_size(events); @@ -52,11 +52,11 @@ static void print_events(Tox_Events *events) tox_events_get_bytes(events, bytes); - Tox_Events *events_copy = tox_events_load(bytes, size); + Tox_Events *events_copy = tox_events_load(sys, bytes, size); ck_assert(events_copy != nullptr); free(bytes); - ck_assert(tox_events_equal(events, events_copy)); + ck_assert(tox_events_equal(sys, events, events_copy)); tox_events_free(events_copy); tox_events_free(events); @@ -64,9 +64,11 @@ static void print_events(Tox_Events *events) static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch) { + const Tox_System *sys = tox_get_system(toxes[0]); + for (uint32_t i = 0; i < 100; ++i) { // Ignore events on tox 1. - print_events(tox_events_iterate(toxes[0], false, nullptr)); + print_events(sys, tox_events_iterate(toxes[0], false, nullptr)); // Check if tox 2 got the message from tox 1. Tox_Events *events = tox_events_iterate(toxes[1], false, nullptr); @@ -74,7 +76,7 @@ static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch) bool success = false; tox_dispatch_invoke(dispatch, events, toxes[1], &success); - print_events(events); + print_events(sys, events); if (success) { return true; @@ -101,6 +103,8 @@ static void test_tox_events(void) ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i); } + const Tox_System *sys = tox_get_system(toxes[0]); + Tox_Err_Dispatch_New err_new; Tox_Dispatch *dispatch = tox_dispatch_new(&err_new); ck_assert_msg(dispatch != nullptr, "failed to create event dispatcher"); @@ -123,8 +127,8 @@ static void test_tox_events(void) while (tox_self_get_connection_status(toxes[0]) == TOX_CONNECTION_NONE || tox_self_get_connection_status(toxes[1]) == TOX_CONNECTION_NONE) { // Ignore connection events for now. - print_events(tox_events_iterate(toxes[0], false, nullptr)); - print_events(tox_events_iterate(toxes[1], false, nullptr)); + print_events(sys, tox_events_iterate(toxes[0], false, nullptr)); + print_events(sys, tox_events_iterate(toxes[1], false, nullptr)); c_sleep(tox_iteration_interval(toxes[0])); } @@ -134,8 +138,8 @@ static void test_tox_events(void) while (tox_friend_get_connection_status(toxes[0], 0, nullptr) == TOX_CONNECTION_NONE || tox_friend_get_connection_status(toxes[1], 0, nullptr) == TOX_CONNECTION_NONE) { // Ignore connection events for now. - print_events(tox_events_iterate(toxes[0], false, nullptr)); - print_events(tox_events_iterate(toxes[1], false, nullptr)); + print_events(sys, tox_events_iterate(toxes[0], false, nullptr)); + print_events(sys, tox_events_iterate(toxes[1], false, nullptr)); c_sleep(tox_iteration_interval(toxes[0])); } diff --git a/azure-pipelines.yml b/azure-pipelines.yml index dee7204ac6..0b0bd29c29 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ jobs: shared: conan.shared: "True" steps: - - bash: python -m pip install conan + - bash: python -m pip install conan==1.59.0 - bash: git submodule update --init --recursive - bash: conan install -if _build -o with_tests=True -o shared=$(conan.shared) . - bash: CONAN_CPU_COUNT=50 CTEST_OUTPUT_ON_FAILURE=1 conan build -bf _build -if _build . diff --git a/codecov.yml b/codecov.yml index 45b48ca22b..439c6e76d1 100644 --- a/codecov.yml +++ b/codecov.yml @@ -11,3 +11,7 @@ coverage: # because of the above range, but toxcore coverage fluctuates a lot due # to low coverage of error paths that sometimes happen. threshold: 2% + +ignore: + - "auto_tests" # ignore tests in coverage analysis + - "other" # we don't test the bootstrap daemon diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 4128992e4a..e59f9eedea 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -144,15 +144,17 @@ int main(int argc, char *argv[]) } const Random *rng = system_random(); - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); + const Network *ns = system_network(); + const Memory *mem = system_memory(); + + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); const uint16_t start_port = PORT; const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); - const Network *ns = system_network(); - DHT *dht = new_dht(logger, rng, ns, mono_time, new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr), true, true); - Onion *onion = new_onion(logger, mono_time, rng, dht); + DHT *dht = new_dht(logger, mem, rng, ns, mono_time, new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr), true, true); + Onion *onion = new_onion(logger, mem, mono_time, rng, dht); Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht); GC_Announces_List *gc_announces_list = new_gca_list(); - Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); + Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht); #ifdef DHT_NODE_EXTRA_PACKETS bootstrap_set_callbacks(dht_get_net(dht), DHT_VERSION_NUMBER, DHT_MOTD, sizeof(DHT_MOTD)); @@ -173,7 +175,7 @@ int main(int argc, char *argv[]) #ifdef TCP_RELAY_ENABLED #define NUM_PORTS 3 uint16_t ports[NUM_PORTS] = {443, 3389, PORT}; - TCP_Server *tcp_s = new_TCP_server(logger, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding); + TCP_Server *tcp_s = new_TCP_server(logger, mem, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding); if (tcp_s == nullptr) { printf("TCP server failed to initialize.\n"); diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index 851b672409..71bc96b045 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -23e142729a72618462018b25c830dbad5b023d0fa3de9ae53d376f43dc46b481 /usr/local/bin/tox-bootstrapd +6f4ec4239de5ea05ae341271bbda4cb78535f943a693321648ee1ab043a203d2 /usr/local/bin/tox-bootstrapd diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index d12caf9bd2..7efd2c889d 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -280,15 +280,17 @@ int main(int argc, char *argv[]) } const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM); + const Memory *mem = system_memory(); + const Random *rng = system_random(); const Network *ns = system_network(); - Networking_Core *net = new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr); + Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); if (net == nullptr) { if (enable_ipv6 && enable_ipv4_fallback) { log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n"); enable_ipv6 = 0; ip_init(&ip, enable_ipv6); - net = new_networking_ex(logger, ns, &ip, start_port, end_port, nullptr); + net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr); if (net == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't fallback to IPv4. Exiting.\n"); @@ -308,7 +310,7 @@ int main(int argc, char *argv[]) } } - Mono_Time *const mono_time = mono_time_new(nullptr, nullptr); + Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr); if (mono_time == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize monotonic timer. Exiting.\n"); @@ -322,12 +324,11 @@ int main(int argc, char *argv[]) mono_time_update(mono_time); - const Random *rng = system_random(); - DHT *const dht = new_dht(logger, rng, ns, mono_time, net, true, enable_lan_discovery); + DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery); if (dht == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n"); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(motd); @@ -341,7 +342,7 @@ int main(int argc, char *argv[]) if (forwarding == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize forwarding. Exiting.\n"); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(motd); @@ -350,13 +351,13 @@ int main(int argc, char *argv[]) return 1; } - Announcements *announce = new_announcements(logger, rng, mono_time, forwarding); + Announcements *announce = new_announcements(logger, mem, rng, mono_time, forwarding); if (announce == nullptr) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize DHT announcements. Exiting.\n"); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(motd); @@ -372,7 +373,7 @@ int main(int argc, char *argv[]) kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(motd); @@ -381,14 +382,14 @@ int main(int argc, char *argv[]) return 1; } - Onion *onion = new_onion(logger, mono_time, rng, dht); + Onion *onion = new_onion(logger, mem, mono_time, rng, dht); if (!onion) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n"); kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(motd); @@ -397,7 +398,7 @@ int main(int argc, char *argv[]) return 1; } - Onion_Announce *onion_a = new_onion_announce(logger, rng, mono_time, dht); + Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht); if (!onion_a) { log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n"); @@ -406,7 +407,7 @@ int main(int argc, char *argv[]) kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(motd); @@ -429,7 +430,7 @@ int main(int argc, char *argv[]) kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(motd); @@ -450,7 +451,7 @@ int main(int argc, char *argv[]) kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(tcp_relay_ports); @@ -469,14 +470,15 @@ int main(int argc, char *argv[]) kill_forwarding(forwarding); kill_onion(onion); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); free(tcp_relay_ports); return 1; } - tcp_server = new_TCP_server(logger, rng, ns, enable_ipv6, tcp_relay_port_count, tcp_relay_ports, + tcp_server = new_TCP_server(logger, mem, rng, ns, enable_ipv6, + tcp_relay_port_count, tcp_relay_ports, dht_get_self_secret_key(dht), onion, forwarding); free(tcp_relay_ports); @@ -515,7 +517,7 @@ int main(int argc, char *argv[]) kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); return 1; @@ -533,7 +535,7 @@ int main(int argc, char *argv[]) kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); return 1; @@ -616,7 +618,7 @@ int main(int argc, char *argv[]) kill_announcements(announce); kill_forwarding(forwarding); kill_dht(dht); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); kill_networking(net); logger_kill(logger); diff --git a/other/docker/coverage/Dockerfile b/other/docker/coverage/Dockerfile index 7e103c5597..031afc7b91 100644 --- a/other/docker/coverage/Dockerfile +++ b/other/docker/coverage/Dockerfile @@ -1,5 +1,5 @@ FROM toxchat/c-toxcore:sources AS src -FROM ubuntu:20.04 AS build +FROM ubuntu:22.04 AS build RUN apt-get update && \ DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ @@ -31,8 +31,8 @@ SHELL ["/bin/bash", "-c"] WORKDIR /work COPY --from=src /src/ /work/ RUN source .github/scripts/flags-coverage.sh \ - && go get github.com/things-go/go-socks5 \ - && go build other/proxy/proxy_server.go \ + && go version \ + && (cd other/proxy && go get github.com/things-go/go-socks5 && go build proxy_server.go) \ && cmake -B_build -H. -GNinja \ -DCMAKE_C_FLAGS="$C_FLAGS" \ -DCMAKE_CXX_FLAGS="$CXX_FLAGS" \ @@ -46,6 +46,7 @@ RUN source .github/scripts/flags-coverage.sh \ -DAUTOTEST=ON \ -DPROXY_TEST=ON \ -DUSE_IPV6=OFF \ + -DTEST_TIMEOUT_SECONDS=30 \ && cmake --build _build --parallel 8 --target install WORKDIR /work/_build diff --git a/other/proxy/go.mod b/other/proxy/go.mod index 1f7b3964c4..32997cbc36 100644 --- a/other/proxy/go.mod +++ b/other/proxy/go.mod @@ -1,5 +1,5 @@ module github.com/TokTok/c-toxcore/other/proxy -go 1.16 +go 1.18 -require github.com/things-go/go-socks5 v0.0.2 +require github.com/things-go/go-socks5 v0.0.3 diff --git a/other/proxy/go.sum b/other/proxy/go.sum index 35434d40cd..7cd257cdf3 100644 --- a/other/proxy/go.sum +++ b/other/proxy/go.sum @@ -4,6 +4,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ 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= +github.com/things-go/go-socks5 v0.0.3 h1:QtlIhkwDuLNCwW3wnt2uTjn1mQzpyjnwct2xdPuqroI= +github.com/things-go/go-socks5 v0.0.3/go.mod h1:f8Zx+n8kfzyT90hXM767cP6sysAud93+t9rV90IgMcg= 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= diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index b36d2a1558..4c2c8f85ff 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -92,7 +92,8 @@ int main(int argc, char *argv[]) exit(0); } - Mono_Time *const mono_time = mono_time_new(nullptr, nullptr); + const Memory *mem = system_memory(); + Mono_Time *const mono_time = mono_time_new(mem, nullptr, nullptr); if (mono_time == nullptr) { fputs("Failed to allocate monotonic timer datastructure\n", stderr); @@ -102,7 +103,7 @@ int main(int argc, char *argv[]) Messenger_Options options = {0}; options.ipv6enabled = ipv6enabled; Messenger_Error err; - m = new_messenger(mono_time, system_random(), system_network(), &options, &err); + m = new_messenger(mono_time, mem, system_random(), system_network(), &options, &err); if (!m) { fprintf(stderr, "Failed to allocate messenger datastructure: %d\n", err); diff --git a/testing/fuzzing/BUILD.bazel b/testing/fuzzing/BUILD.bazel index 9f8c0b9607..386516d72b 100644 --- a/testing/fuzzing/BUILD.bazel +++ b/testing/fuzzing/BUILD.bazel @@ -28,6 +28,7 @@ cc_library( cc_fuzz_test( name = "bootstrap_fuzz_test", + #size = "small", srcs = ["bootstrap_harness.cc"], copts = ["-UNDEBUG"], corpus = ["//tools/toktok-fuzzer/corpus:bootstrap_fuzzer"], @@ -42,6 +43,7 @@ cc_fuzz_test( cc_fuzz_test( name = "e2e_fuzz_test", + #size = "small", srcs = ["e2e_fuzz_test.cc"], copts = ["-UNDEBUG"], corpus = ["//tools/toktok-fuzzer/corpus:e2e_fuzz_test"], @@ -57,6 +59,7 @@ cc_fuzz_test( cc_fuzz_test( name = "toxsave_fuzz_test", + #size = "small", srcs = ["toxsave_harness.cc"], copts = ["-UNDEBUG"], corpus = ["//tools/toktok-fuzzer/corpus:toxsave_fuzzer"], @@ -89,6 +92,7 @@ fuzzing_binary( cc_fuzz_test( name = "protodump_reduce", + #size = "small", srcs = ["protodump_reduce.cc"], copts = ["-UNDEBUG"], deps = [ diff --git a/testing/fuzzing/bootstrap_harness.cc b/testing/fuzzing/bootstrap_harness.cc index 6a9b0cbd22..9ffb69d1f1 100644 --- a/testing/fuzzing/bootstrap_harness.cc +++ b/testing/fuzzing/bootstrap_harness.cc @@ -169,7 +169,7 @@ void TestBootstrap(Fuzz_Data &input) 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)); + assert(tox_events_equal(sys.sys.get(), 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 diff --git a/testing/fuzzing/e2e_fuzz_test.cc b/testing/fuzzing/e2e_fuzz_test.cc index c54304c5c3..f5258853e5 100644 --- a/testing/fuzzing/e2e_fuzz_test.cc +++ b/testing/fuzzing/e2e_fuzz_test.cc @@ -134,6 +134,8 @@ void setup_callbacks(Tox_Dispatch *dispatch) void TestEndToEnd(Fuzz_Data &input) { Fuzz_System sys(input); + // Used for places where we want all allocations to succeed. + Null_System null_sys; Ptr opts(tox_options_new(nullptr), tox_options_free); assert(opts != nullptr); @@ -170,7 +172,7 @@ void TestEndToEnd(Fuzz_Data &input) 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)); + assert(tox_events_equal(null_sys.sys.get(), 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 diff --git a/testing/fuzzing/fuzz_support.cc b/testing/fuzzing/fuzz_support.cc index 5ee2457066..510a6563f3 100644 --- a/testing/fuzzing/fuzz_support.cc +++ b/testing/fuzzing/fuzz_support.cc @@ -62,6 +62,33 @@ static int recv_common(Fuzz_Data &input, uint8_t *buf, size_t buf_len) return res; } +template +static void *alloc_common(Fuzz_Data &data, F func) +{ + CONSUME1_OR_RETURN_VAL(const uint8_t want_alloc, data, func()); + if (!want_alloc) { + return nullptr; + } + return func(); +} + +static constexpr Memory_Funcs fuzz_memory_funcs = { + /* .malloc = */ + ![](Fuzz_System *self, uint32_t size) { + return alloc_common(self->data, [=]() { return std::malloc(size); }); + }, + /* .calloc = */ + ![](Fuzz_System *self, uint32_t nmemb, uint32_t size) { + return alloc_common(self->data, [=]() { return std::calloc(nmemb, size); }); + }, + /* .realloc = */ + ![](Fuzz_System *self, void *ptr, uint32_t size) { + return alloc_common(self->data, [=]() { return std::realloc(ptr, size); }); + }, + /* .free = */ + ![](Fuzz_System *self, void *ptr) { std::free(ptr); }, +}; + static constexpr Network_Funcs fuzz_network_funcs = { /* .close = */ ![](Fuzz_System *self, int sock) { return 0; }, /* .accept = */ ![](Fuzz_System *self, int sock) { return 1337; }, @@ -149,6 +176,7 @@ static constexpr Random_Funcs fuzz_random_funcs = { Fuzz_System::Fuzz_System(Fuzz_Data &input) : System{ std::make_unique(), + std::make_unique(Memory{&fuzz_memory_funcs, this}), std::make_unique(Network{&fuzz_network_funcs, this}), std::make_unique(Random{&fuzz_random_funcs, this}), } @@ -156,10 +184,22 @@ Fuzz_System::Fuzz_System(Fuzz_Data &input) { sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_user_data = this; + sys->mem = mem.get(); sys->ns = ns.get(); sys->rng = rng.get(); } +static constexpr Memory_Funcs null_memory_funcs = { + /* .malloc = */ + ![](Null_System *self, uint32_t size) { return std::malloc(size); }, + /* .calloc = */ + ![](Null_System *self, uint32_t nmemb, uint32_t size) { return std::calloc(nmemb, size); }, + /* .realloc = */ + ![](Null_System *self, void *ptr, uint32_t size) { return std::realloc(ptr, size); }, + /* .free = */ + ![](Null_System *self, void *ptr) { std::free(ptr); }, +}; + static constexpr Network_Funcs null_network_funcs = { /* .close = */ ![](Null_System *self, int sock) { return 0; }, /* .accept = */ ![](Null_System *self, int sock) { return 1337; }, @@ -224,12 +264,14 @@ static constexpr Random_Funcs null_random_funcs = { Null_System::Null_System() : System{ std::make_unique(), + std::make_unique(Memory{&null_memory_funcs, this}), std::make_unique(Network{&null_network_funcs, this}), std::make_unique(Random{&null_random_funcs, this}), } { sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_user_data = this; + sys->mem = mem.get(); sys->ns = ns.get(); sys->rng = rng.get(); } @@ -244,6 +286,8 @@ static uint16_t get_port(const Network_Addr *addr) } } +static constexpr Memory_Funcs record_memory_funcs = null_memory_funcs; + static constexpr Network_Funcs record_network_funcs = { /* .close = */ ![](Record_System *self, int sock) { return 0; }, /* .accept = */ ![](Record_System *self, int sock) { return 2; }, @@ -348,6 +392,7 @@ static constexpr Random_Funcs record_random_funcs = { Record_System::Record_System(Global &global, uint64_t seed, const char *name) : System{ std::make_unique(), + std::make_unique(Memory{&record_memory_funcs, this}), std::make_unique(Network{&record_network_funcs, this}), std::make_unique(Random{&record_random_funcs, this}), } @@ -357,6 +402,7 @@ Record_System::Record_System(Global &global, uint64_t seed, const char *name) { sys->mono_time_callback = ![](Fuzz_System *self) { return self->clock; }; sys->mono_time_user_data = this; + sys->mem = mem.get(); sys->ns = ns.get(); sys->rng = rng.get(); } diff --git a/testing/fuzzing/fuzz_support.h b/testing/fuzzing/fuzz_support.h index 1a5bff1444..a20d85b4f2 100644 --- a/testing/fuzzing/fuzz_support.h +++ b/testing/fuzzing/fuzz_support.h @@ -59,6 +59,23 @@ struct Fuzz_Data { } \ DECL = INPUT.consume1() +/** @brief Consumes 1 byte of the fuzzer input or returns a value if no data + * available. + * + * This advances the fuzzer input data by 1 byte and consumes that byte in the + * declaration. + * + * @example + * @code + * CONSUME1_OR_RETURN_VAL(const uint8_t one_byte, input, nullptr); + * @endcode + */ +#define CONSUME1_OR_RETURN_VAL(DECL, INPUT, VAL) \ + if (INPUT.size < 1) { \ + return VAL; \ + } \ + DECL = INPUT.consume1() + /** @brief Consumes SIZE bytes of the fuzzer input or returns if not enough data available. * * This advances the fuzzer input data by SIZE byte and consumes those bytes in @@ -100,11 +117,13 @@ void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&... args) return fuzz_select_target(selector, input, std::forward(args)...); } +struct Memory; struct Network; struct Random; struct System { std::unique_ptr sys; + std::unique_ptr mem; std::unique_ptr ns; std::unique_ptr rng; diff --git a/testing/fuzzing/fuzz_tox.h b/testing/fuzzing/fuzz_tox.h index 9ab92be2c7..b5864e78d3 100644 --- a/testing/fuzzing/fuzz_tox.h +++ b/testing/fuzzing/fuzz_tox.h @@ -62,13 +62,14 @@ struct with { /** @brief Construct a Networking_Core object using the Network vtable passed. * - * Use `with{} >> with{input, ns} >> ...` to construct + * Use `with{} >> with{input, ns, mem} >> ...` to construct * a logger and pass it to the Networking_Core constructor function. */ template <> struct with { Fuzz_Data &input_; const Network *ns_; + const Memory *mem_; Ptr logger_{nullptr, logger_kill}; friend with operator>>(with f, with self) @@ -82,7 +83,7 @@ struct with { { with{input_} >> [&f, this](const IP_Port &ipp) { Ptr net( - new_networking_ex(logger_.get(), ns_, &ipp.ip, ipp.port, ipp.port + 100, nullptr), + new_networking_ex(logger_.get(), mem_, ns_, &ipp.ip, ipp.port, ipp.port + 100, nullptr), kill_networking); if (net == nullptr) { return; diff --git a/testing/fuzzing/protodump.cc b/testing/fuzzing/protodump.cc index 30eef5eb7e..5b07569e78 100644 --- a/testing/fuzzing/protodump.cc +++ b/testing/fuzzing/protodump.cc @@ -244,12 +244,12 @@ void RecordBootstrap() Tox_Events *events; events = tox_events_iterate(tox1, true, &error_iterate); - assert(tox_events_equal(events, events)); + assert(tox_events_equal(sys1.sys.get(), events, events)); tox_dispatch_invoke(dispatch, events, tox1, &done1); tox_events_free(events); events = tox_events_iterate(tox2, true, &error_iterate); - assert(tox_events_equal(events, events)); + assert(tox_events_equal(sys2.sys.get(), events, events)); tox_dispatch_invoke(dispatch, events, tox2, &done2); tox_events_free(events); diff --git a/testing/fuzzing/protodump_reduce.cc b/testing/fuzzing/protodump_reduce.cc index 40aa5ae312..2bfe3a9b5c 100644 --- a/testing/fuzzing/protodump_reduce.cc +++ b/testing/fuzzing/protodump_reduce.cc @@ -172,7 +172,7 @@ void TestEndToEnd(Fuzz_Data &input) 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)); + assert(tox_events_equal(tox_get_system(tox), events, events)); tox_dispatch_invoke(dispatch, events, tox, nullptr); tox_events_free(events); sys.clock += std::max(System::MIN_ITERATION_INTERVAL, random_u08(sys.rng.get())); diff --git a/toxav/groupav.c b/toxav/groupav.c index 583304c6a3..4e3ad2cc49 100644 --- a/toxav/groupav.c +++ b/toxav/groupav.c @@ -536,7 +536,7 @@ bool groupchat_av_enabled(const Group_Chats *g_c, uint32_t groupnumber) */ int add_av_groupchat(const Logger *log, Tox *tox, Group_Chats *g_c, audio_data_cb *audio_callback, void *userdata) { - const int groupnumber = add_groupchat(g_c, &tox->rng, GROUPCHAT_TYPE_AV); + const int groupnumber = add_groupchat(g_c, tox->sys.rng, GROUPCHAT_TYPE_AV); if (groupnumber == -1) { return -1; diff --git a/toxav/toxav.c b/toxav/toxav.c index 4b14aa8388..bdec43b504 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -181,7 +181,7 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error) av->tox = tox; av->m = m; - av->toxav_mono_time = mono_time_new(nullptr, nullptr); + av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr); av->msi = msi_new(av->m); if (av->msi == nullptr) { @@ -239,7 +239,7 @@ void toxav_kill(ToxAV *av) } } - mono_time_free(av->toxav_mono_time); + mono_time_free(av->tox->sys.mem, av->toxav_mono_time); pthread_mutex_unlock(av->mutex); pthread_mutex_destroy(av->mutex); diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 730b84e974..4701cf437d 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -23,6 +23,28 @@ cc_library( deps = [":attributes"], ) +cc_library( + name = "mem", + srcs = ["mem.c"], + hdrs = ["mem.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [ + ":attributes", + ":ccompat", + ], +) + +cc_test( + name = "mem_test", + size = "small", + srcs = ["mem_test.cc"], + deps = [ + ":mem", + "@com_google_googletest//:gtest", + "@com_google_googletest//:gtest_main", + ], +) + cc_library( name = "util", srcs = ["util.c"], @@ -37,6 +59,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", "@pthread", ], ) @@ -175,6 +198,7 @@ cc_library( deps = [ ":attributes", ":ccompat", + ":mem", "@pthread", ], ) @@ -204,6 +228,7 @@ cc_library( deps = [ ":ccompat", ":crypto_core", + ":mem", ":mono_time", ], ) @@ -223,6 +248,7 @@ cc_library( ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", ":util", "@libsodium", @@ -260,6 +286,7 @@ cc_library( deps = [ ":ccompat", ":crypto_core", + ":mem", ":mono_time", ":util", ], @@ -315,6 +342,7 @@ cc_library( ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", ":network", ":ping_array", @@ -413,6 +441,7 @@ cc_library( ":attributes", ":ccompat", ":crypto_core", + ":mem", ":network", ], ) @@ -766,6 +795,7 @@ cc_library( ":group", ":group_moderation", ":logger", + ":mem", ":mono_time", ":network", "//c-toxcore/toxencryptsave:defines", @@ -810,6 +840,7 @@ cc_library( ":bin_pack", ":bin_unpack", ":ccompat", + ":mem", ":tox", ":tox_unpack", "//c-toxcore/third_party:cmp", @@ -822,6 +853,7 @@ cc_test( srcs = ["tox_events_test.cc"], deps = [ ":crypto_core", + ":tox", ":tox_events", "@com_google_googletest//:gtest", "@com_google_googletest//:gtest_main", @@ -832,7 +864,10 @@ cc_fuzz_test( name = "tox_events_fuzz_test", srcs = ["tox_events_fuzz_test.cc"], corpus = ["//tools/toktok-fuzzer/corpus:tox_events_fuzz_test"], - deps = [":tox_events"], + deps = [ + ":tox_events", + "//c-toxcore/testing/fuzzing:fuzz_support", + ], ) cc_library( diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 91f0e0ae47..1b4062cbbe 100644 --- a/toxcore/DHT.c +++ b/toxcore/DHT.c @@ -91,6 +91,7 @@ struct DHT { const Logger *log; const Network *ns; Mono_Time *mono_time; + const Memory *mem; const Random *rng; Networking_Core *net; @@ -414,12 +415,13 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_ } } -int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], +int dht_create_packet(const Memory *mem, const Random *rng, + const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *shared_key, const uint8_t type, const uint8_t *plain, size_t plain_length, uint8_t *packet, size_t length) { - uint8_t *encrypted = (uint8_t *)malloc(plain_length + CRYPTO_MAC_SIZE); + uint8_t *encrypted = (uint8_t *)mem_balloc(mem, plain_length + CRYPTO_MAC_SIZE); uint8_t nonce[CRYPTO_NONCE_SIZE]; if (encrypted == nullptr) { @@ -431,12 +433,12 @@ int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_ const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted); if (encrypted_length == -1) { - free(encrypted); + mem_delete(mem, encrypted); return -1; } if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) { - free(encrypted); + mem_delete(mem, encrypted); return -1; } @@ -445,7 +447,7 @@ int dht_create_packet(const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_ memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE, nonce, CRYPTO_NONCE_SIZE); memcpy(packet + 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE, encrypted, encrypted_length); - free(encrypted); + mem_delete(mem, encrypted); return 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length; } @@ -937,7 +939,8 @@ static bool send_announce_ping(DHT *dht, const uint8_t *public_key, const IP_Por uint8_t request[1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + sizeof(plain) + CRYPTO_MAC_SIZE]; - if (dht_create_packet(dht->rng, dht->self_public_key, shared_key, NET_PACKET_DATA_SEARCH_REQUEST, + if (dht_create_packet(dht->mem, dht->rng, + dht->self_public_key, shared_key, NET_PACKET_DATA_SEARCH_REQUEST, plain, sizeof(plain), request, sizeof(request)) != sizeof(request)) { return false; } @@ -1008,12 +1011,12 @@ static bool store_node_ok(const Client_data *client, uint64_t cur_time, const ui } non_null() -static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int length, +static void sort_client_list(const Memory *mem, Client_data *list, uint64_t cur_time, unsigned int length, const uint8_t *comp_public_key) { // Pass comp_public_key to qsort with each Client_data entry, so the // comparison function can use it as the base of comparison. - DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)calloc(length, sizeof(DHT_Cmp_Data)); + DHT_Cmp_Data *cmp_list = (DHT_Cmp_Data *)mem_valloc(mem, length, sizeof(DHT_Cmp_Data)); if (cmp_list == nullptr) { return; @@ -1031,7 +1034,7 @@ static void sort_client_list(Client_data *list, uint64_t cur_time, unsigned int list[i] = cmp_list[i].entry; } - free(cmp_list); + mem_delete(mem, cmp_list); } non_null() @@ -1092,7 +1095,7 @@ static bool replace_all(const DHT *dht, return false; } - sort_client_list(list, dht->cur_time, length, comp_public_key); + sort_client_list(dht->mem, list, dht->cur_time, length, comp_public_key); Client_data *const client = &list[0]; pk_copy(client->public_key, public_key); @@ -1392,7 +1395,7 @@ bool dht_getnodes(DHT *dht, const IP_Port *ip_port, const uint8_t *public_key, c const uint8_t *shared_key = dht_get_shared_key_sent(dht, public_key); - const int len = dht_create_packet(dht->rng, + const int len = dht_create_packet(dht->mem, dht->rng, dht->self_public_key, shared_key, NET_PACKET_GET_NODES, plain, sizeof(plain), data, sizeof(data)); @@ -1442,7 +1445,7 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE; VLA(uint8_t, data, 1 + nodes_length + length + crypto_size); - const int len = dht_create_packet(dht->rng, + const int len = dht_create_packet(dht->mem, dht->rng, dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6, plain, 1 + nodes_length + length, data, SIZEOF_VLA(data)); @@ -1681,7 +1684,7 @@ int dht_addfriend(DHT *dht, const uint8_t *public_key, dht_ip_cb *ip_callback, return 0; } - DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1)); + DHT_Friend *const temp = (DHT_Friend *)mem_vrealloc(dht->mem, dht->friends_list, dht->num_friends + 1, sizeof(DHT_Friend)); if (temp == nullptr) { return -1; @@ -1726,12 +1729,12 @@ int dht_delfriend(DHT *dht, const uint8_t *public_key, uint32_t lock_token) } if (dht->num_friends == 0) { - free(dht->friends_list); + mem_delete(dht->mem, dht->friends_list); dht->friends_list = nullptr; return 0; } - DHT_Friend *const temp = (DHT_Friend *)realloc(dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); + DHT_Friend *const temp = (DHT_Friend *)mem_vrealloc(dht->mem, dht->friends_list, dht->num_friends, sizeof(DHT_Friend)); if (temp == nullptr) { return -1; @@ -1784,14 +1787,14 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co const uint64_t temp_time = mono_time_get(dht->mono_time); uint32_t num_nodes = 0; - Client_data **client_list = (Client_data **)calloc(list_count * 2, sizeof(Client_data *)); - IPPTsPng **assoc_list = (IPPTsPng **)calloc(list_count * 2, sizeof(IPPTsPng *)); + Client_data **client_list = (Client_data **)mem_valloc(dht->mem, list_count * 2, sizeof(Client_data *)); + IPPTsPng **assoc_list = (IPPTsPng **)mem_valloc(dht->mem, list_count * 2, sizeof(IPPTsPng *)); unsigned int sort = 0; bool sort_ok = false; if (client_list == nullptr || assoc_list == nullptr) { - free(assoc_list); - free(client_list); + mem_delete(dht->mem, assoc_list); + mem_delete(dht->mem, client_list); return 0; } @@ -1831,7 +1834,7 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co } if (sortable && sort_ok) { - sort_client_list(list, dht->cur_time, list_count, public_key); + sort_client_list(dht->mem, list, dht->cur_time, list_count, public_key); } if (num_nodes > 0 && (mono_time_is_timeout(dht->mono_time, *lastgetnode, GET_NODE_INTERVAL) @@ -1848,8 +1851,8 @@ static uint8_t do_ping_and_sendnode_requests(DHT *dht, uint64_t *lastgetnode, co ++*bootstrap_times; } - free(assoc_list); - free(client_list); + mem_delete(dht->mem, assoc_list); + mem_delete(dht->mem, client_list); return not_kill; } @@ -2606,14 +2609,15 @@ static int handle_LANdiscovery(void *object, const IP_Port *source, const uint8_ /*----------------------------------------------------------------------------------*/ -DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net, +DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, + Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled) { if (net == nullptr) { return nullptr; } - DHT *const dht = (DHT *)calloc(1, sizeof(DHT)); + DHT *const dht = (DHT *)mem_alloc(mem, sizeof(DHT)); if (dht == nullptr) { return nullptr; @@ -2625,11 +2629,12 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time dht->log = log; dht->net = net; dht->rng = rng; + dht->mem = mem; dht->hole_punching_enabled = hole_punching_enabled; dht->lan_discovery_enabled = lan_discovery_enabled; - dht->ping = ping_new(mono_time, rng, dht); + dht->ping = ping_new(mem, mono_time, rng, dht); if (dht->ping == nullptr) { kill_dht(dht); @@ -2648,8 +2653,8 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time crypto_new_keypair(rng, dht->self_public_key, dht->self_secret_key); - dht->shared_keys_recv = shared_key_cache_new(mono_time, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); - dht->shared_keys_sent = shared_key_cache_new(mono_time, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + dht->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + dht->shared_keys_sent = shared_key_cache_new(mono_time, mem, dht->self_secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (dht->shared_keys_recv == nullptr || dht->shared_keys_sent == nullptr) { kill_dht(dht); @@ -2657,7 +2662,7 @@ DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time } - dht->dht_ping_array = ping_array_new(DHT_PING_ARRAY_SIZE, PING_TIMEOUT); + dht->dht_ping_array = ping_array_new(mem, DHT_PING_ARRAY_SIZE, PING_TIMEOUT); if (dht->dht_ping_array == nullptr) { kill_dht(dht); @@ -2722,11 +2727,11 @@ void kill_dht(DHT *dht) shared_key_cache_free(dht->shared_keys_recv); shared_key_cache_free(dht->shared_keys_sent); ping_array_kill(dht->dht_ping_array); - ping_kill(dht->ping); - free(dht->friends_list); - free(dht->loaded_nodes_list); + ping_kill(dht->mem, dht->ping); + mem_delete(dht->mem, dht->friends_list); + mem_delete(dht->mem, dht->loaded_nodes_list); crypto_memzero(dht->self_secret_key, sizeof(dht->self_secret_key)); - free(dht); + mem_delete(dht->mem, dht); } /* new DHT format for load/save, more robust and forward compatible */ @@ -2780,7 +2785,7 @@ void dht_save(const DHT *dht, uint8_t *data) /* get right offset. we write the actual header later. */ data = state_write_section_header(data, DHT_STATE_COOKIE_TYPE, 0, 0); - Node_format *clients = (Node_format *)calloc(MAX_SAVED_DHT_NODES, sizeof(Node_format)); + Node_format *clients = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format)); if (clients == nullptr) { LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES); @@ -2829,7 +2834,7 @@ void dht_save(const DHT *dht, uint8_t *data) state_write_section_header(old_data, DHT_STATE_COOKIE_TYPE, pack_nodes(dht->log, data, sizeof(Node_format) * num, clients, num), DHT_STATE_TYPE_NODES); - free(clients); + mem_delete(dht->mem, clients); } /** Bootstrap from this number of nodes every time `dht_connect_after_load()` is called */ @@ -2847,7 +2852,7 @@ int dht_connect_after_load(DHT *dht) /* DHT is connected, stop. */ if (dht_non_lan_connected(dht)) { - free(dht->loaded_nodes_list); + mem_delete(dht->mem, dht->loaded_nodes_list); dht->loaded_nodes_list = nullptr; dht->loaded_num_nodes = 0; return 0; @@ -2873,9 +2878,9 @@ static State_Load_Status dht_load_state_callback(void *outer, const uint8_t *dat break; } - free(dht->loaded_nodes_list); + mem_delete(dht->mem, dht->loaded_nodes_list); // Copy to loaded_clients_list - dht->loaded_nodes_list = (Node_format *)calloc(MAX_SAVED_DHT_NODES, sizeof(Node_format)); + dht->loaded_nodes_list = (Node_format *)mem_valloc(dht->mem, MAX_SAVED_DHT_NODES, sizeof(Node_format)); if (dht->loaded_nodes_list == nullptr) { LOGGER_ERROR(dht->log, "could not allocate %u nodes", MAX_SAVED_DHT_NODES); diff --git a/toxcore/DHT.h b/toxcore/DHT.h index 86ac4f9d40..95f442e79f 100644 --- a/toxcore/DHT.h +++ b/toxcore/DHT.h @@ -14,6 +14,7 @@ #include "attributes.h" #include "crypto_core.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" #include "ping_array.h" @@ -219,7 +220,7 @@ int pack_ip_port(const Logger *logger, uint8_t *data, uint16_t length, const IP_ * @retval -1 on failure. */ non_null() -int dht_create_packet(const Random *rng, +int dht_create_packet(const Memory *mem, const Random *rng, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE], const uint8_t *shared_key, const uint8_t type, const uint8_t *plain, size_t plain_length, @@ -494,8 +495,8 @@ int dht_load(DHT *dht, const uint8_t *data, uint32_t length); /** Initialize DHT. */ non_null() -DHT *new_dht(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, Networking_Core *net, - bool hole_punching_enabled, bool lan_discovery_enabled); +DHT *new_dht(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, + Mono_Time *mono_time, Networking_Core *net, bool hole_punching_enabled, bool lan_discovery_enabled); nullable(1) void kill_dht(DHT *dht); diff --git a/toxcore/DHT_test.cc b/toxcore/DHT_test.cc index 3014c0b256..84d3b9820a 100644 --- a/toxcore/DHT_test.cc +++ b/toxcore/DHT_test.cc @@ -187,12 +187,14 @@ TEST(Request, CreateAndParse) TEST(AnnounceNodes, SetAndTest) { - Logger *log = logger_new(); - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); const Network *ns = system_network(); - Networking_Core *net = new_networking_no_udp(log, ns); - DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true); + const Memory *mem = system_memory(); + + Logger *log = logger_new(); + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); + Networking_Core *net = new_networking_no_udp(log, mem, ns); + DHT *dht = new_dht(log, mem, rng, ns, mono_time, net, true, true); ASSERT_NE(dht, nullptr); uint8_t pk_data[CRYPTO_PUBLIC_KEY_SIZE]; @@ -224,7 +226,7 @@ TEST(AnnounceNodes, SetAndTest) kill_dht(dht); kill_networking(net); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); logger_kill(log); } diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index e5f0ddf91d..70df82b39e 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -39,6 +39,8 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/events/self_connection_status.c \ ../toxcore/DHT.h \ ../toxcore/DHT.c \ + ../toxcore/mem.h \ + ../toxcore/mem.c \ ../toxcore/mono_time.h \ ../toxcore/mono_time.c \ ../toxcore/network.h \ diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 118c7d946c..f5ae68a0f2 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -41,18 +41,18 @@ bool friend_is_valid(const Messenger *m, int32_t friendnumber) /** @brief Set the size of the friend list to numfriends. * - * @retval -1 if realloc fails. + * @retval -1 if mem_vrealloc fails. */ non_null() static int realloc_friendlist(Messenger *m, uint32_t num) { if (num == 0) { - free(m->friendlist); + mem_delete(m->mem, m->friendlist); m->friendlist = nullptr; return 0; } - Friend *newfriendlist = (Friend *)realloc(m->friendlist, num * sizeof(Friend)); + Friend *newfriendlist = (Friend *)mem_vrealloc(m->mem, m->friendlist, num, sizeof(Friend)); if (newfriendlist == nullptr) { return -1; @@ -313,7 +313,7 @@ static int clear_receipts(Messenger *m, int32_t friendnumber) while (receipts != nullptr) { struct Receipts *temp_r = receipts->next; - free(receipts); + mem_delete(m->mem, receipts); receipts = temp_r; } @@ -329,7 +329,7 @@ static int add_receipt(Messenger *m, int32_t friendnumber, uint32_t packet_num, return -1; } - struct Receipts *new_receipts = (struct Receipts *)calloc(1, sizeof(struct Receipts)); + struct Receipts *new_receipts = (struct Receipts *)mem_alloc(m->mem, sizeof(struct Receipts)); if (new_receipts == nullptr) { return -1; @@ -430,7 +430,7 @@ static int do_receipts(Messenger *m, int32_t friendnumber, void *userdata) struct Receipts *r_next = receipts->next; - free(receipts); + mem_delete(m->mem, receipts); m->friendlist[friendnumber].receipts_start = r_next; @@ -2915,15 +2915,16 @@ bool m_register_state_plugin(Messenger *m, State_Type type, m_state_size_cb *siz m_state_load_cb *load_callback, m_state_save_cb *save_callback) { - Messenger_State_Plugin *temp = (Messenger_State_Plugin *)realloc(m->options.state_plugins, - sizeof(Messenger_State_Plugin) * (m->options.state_plugins_length + 1)); + const uint32_t new_length = m->options.state_plugins_length + 1; + Messenger_State_Plugin *temp = (Messenger_State_Plugin *)mem_vrealloc( + m->mem, m->options.state_plugins, new_length, sizeof(Messenger_State_Plugin)); if (temp == nullptr) { return false; } m->options.state_plugins = temp; - ++m->options.state_plugins_length; + m->options.state_plugins_length = new_length; const uint8_t index = m->options.state_plugins_length - 1; m->options.state_plugins[index].type = type; @@ -3502,7 +3503,8 @@ static void m_handle_friend_request( * * if error is not NULL it will be set to one of the values in the enum above. */ -Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error) +Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *rng, const Network *ns, + Messenger_Options *options, Messenger_Error *error) { if (options == nullptr) { return nullptr; @@ -3512,20 +3514,21 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *error = MESSENGER_ERROR_OTHER; } - Messenger *m = (Messenger *)calloc(1, sizeof(Messenger)); + Messenger *m = (Messenger *)mem_alloc(mem, sizeof(Messenger)); if (m == nullptr) { return nullptr; } m->mono_time = mono_time; + m->mem = mem; m->rng = rng; m->ns = ns; m->fr = friendreq_new(); if (m->fr == nullptr) { - free(m); + mem_delete(mem, m); return nullptr; } @@ -3533,7 +3536,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network if (m->log == nullptr) { friendreq_kill(m->fr); - free(m); + mem_delete(mem, m); return nullptr; } @@ -3548,17 +3551,17 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network } if (options->udp_disabled) { - m->net = new_networking_no_udp(m->log, m->ns); + m->net = new_networking_no_udp(m->log, m->mem, m->ns); } else { IP ip; ip_init(&ip, options->ipv6enabled); - m->net = new_networking_ex(m->log, m->ns, &ip, options->port_range[0], options->port_range[1], &net_err); + m->net = new_networking_ex(m->log, m->mem, m->ns, &ip, options->port_range[0], options->port_range[1], &net_err); } if (m->net == nullptr) { friendreq_kill(m->fr); logger_kill(m->log); - free(m); + mem_delete(mem, m); if (error != nullptr && net_err == 1) { *error = MESSENGER_ERROR_PORT; @@ -3567,24 +3570,24 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network return nullptr; } - m->dht = new_dht(m->log, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled); + m->dht = new_dht(m->log, m->mem, m->rng, m->ns, m->mono_time, m->net, options->hole_punching_enabled, options->local_discovery_enabled); if (m->dht == nullptr) { kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); - free(m); + mem_delete(mem, m); return nullptr; } - m->net_crypto = new_net_crypto(m->log, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info); + m->net_crypto = new_net_crypto(m->log, m->mem, m->rng, m->ns, m->mono_time, m->dht, &options->proxy_info); if (m->net_crypto == nullptr) { kill_dht(m->dht); kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); - free(m); + mem_delete(mem, m); return nullptr; } @@ -3597,7 +3600,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); - free(m); + mem_delete(mem, m); return nullptr; } @@ -3605,15 +3608,15 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network if (options->dht_announcements_enabled) { m->forwarding = new_forwarding(m->log, m->rng, m->mono_time, m->dht); - m->announce = new_announcements(m->log, m->rng, m->mono_time, m->forwarding); + m->announce = new_announcements(m->log, m->mem, m->rng, m->mono_time, m->forwarding); } else { m->forwarding = nullptr; m->announce = nullptr; } - m->onion = new_onion(m->log, m->mono_time, m->rng, m->dht); - m->onion_a = new_onion_announce(m->log, m->rng, m->mono_time, m->dht); - m->onion_c = new_onion_client(m->log, m->rng, m->mono_time, m->net_crypto); + m->onion = new_onion(m->log, m->mem, m->mono_time, m->rng, m->dht); + m->onion_a = new_onion_announce(m->log, m->mem, m->rng, m->mono_time, m->dht); + m->onion_c = new_onion_client(m->log, m->mem, m->rng, m->mono_time, m->net_crypto); m->fr_c = new_friend_connections(m->log, m->mono_time, m->ns, m->onion_c, options->local_discovery_enabled); if ((options->dht_announcements_enabled && (m->forwarding == nullptr || m->announce == nullptr)) || @@ -3632,7 +3635,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); - free(m); + mem_delete(mem, m); return nullptr; } @@ -3654,15 +3657,16 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); - free(m); + mem_delete(mem, m); return nullptr; } #endif /* VANILLA_NACL */ if (options->tcp_server_port != 0) { - m->tcp_server = new_TCP_server(m->log, m->rng, m->ns, options->ipv6enabled, 1, &options->tcp_server_port, - dht_get_self_secret_key(m->dht), m->onion, m->forwarding); + m->tcp_server = new_TCP_server(m->log, m->mem, m->rng, m->ns, options->ipv6enabled, 1, + &options->tcp_server_port, dht_get_self_secret_key(m->dht), + m->onion, m->forwarding); if (m->tcp_server == nullptr) { kill_onion(m->onion); @@ -3682,7 +3686,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network kill_networking(m->net); friendreq_kill(m->fr); logger_kill(m->log); - free(m); + mem_delete(mem, m); if (error != nullptr) { *error = MESSENGER_ERROR_TCP_SERVER; @@ -3745,11 +3749,11 @@ void kill_messenger(Messenger *m) } logger_kill(m->log); - free(m->friendlist); + mem_delete(m->mem, m->friendlist); friendreq_kill(m->fr); - free(m->options.state_plugins); - free(m); + mem_delete(m->mem, m->options.state_plugins); + mem_delete(m->mem, m); } bool m_is_receiving_file(Messenger *m) diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 8279815277..cabb2af89d 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -245,6 +245,7 @@ typedef struct Friend { struct Messenger { Logger *log; Mono_Time *mono_time; + const Memory *mem; const Random *rng; const Network *ns; @@ -813,7 +814,8 @@ typedef enum Messenger_Error { * if error is not NULL it will be set to one of the values in the enum above. */ non_null() -Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network *ns, Messenger_Options *options, Messenger_Error *error); +Messenger *new_messenger(Mono_Time *mono_time, const Memory *mem, const Random *rng, const Network *ns, + Messenger_Options *options, Messenger_Error *error); /** @brief Run this before closing shop. * diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 1bc0964004..5aec2337f5 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -8,6 +8,7 @@ */ #include "TCP_client.h" +#include #include #include #include @@ -101,12 +102,12 @@ void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value) * @retval false on failure */ non_null() -static bool connect_sock_to(const Logger *logger, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info) +static bool connect_sock_to(const Logger *logger, const Memory *mem, Socket sock, const IP_Port *ip_port, const TCP_Proxy_Info *proxy_info) { if (proxy_info->proxy_type != TCP_PROXY_NONE) { - return net_connect(logger, sock, &proxy_info->ip_port); + return net_connect(mem, logger, sock, &proxy_info->ip_port); } else { - return net_connect(logger, sock, ip_port); + return net_connect(mem, logger, sock, ip_port); } } @@ -151,8 +152,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 TCP_Connection *con0 = &tcp_conn->con; + const int ret = read_TCP_packet(logger, con0->mem, con0->ns, con0->sock, data, sizeof(data) - 1, &con0->ip_port); if (ret == -1) { return 0; @@ -167,9 +168,10 @@ static int proxy_http_read_connection_response(const Logger *logger, const TCP_C while (data_left > 0) { uint8_t temp_data[16]; const uint16_t temp_data_size = min_u16(data_left, sizeof(temp_data)); + const TCP_Connection *con = &tcp_conn->con; - if (read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, temp_data, temp_data_size, - &tcp_conn->con.ip_port) == -1) { + if (read_TCP_packet(logger, con->mem, con->ns, con->sock, temp_data, temp_data_size, + &con->ip_port) == -1) { LOGGER_ERROR(logger, "failed to drain TCP data (but ignoring failure)"); return 1; } @@ -212,7 +214,8 @@ non_null() static int socks5_read_handshake_response(const Logger *logger, const TCP_Client_Connection *tcp_conn) { uint8_t data[2]; - const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port); + const TCP_Connection *con = &tcp_conn->con; + const int ret = read_TCP_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port); if (ret == -1) { return 0; @@ -262,7 +265,8 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP { if (net_family_is_ipv4(tcp_conn->ip_port.ip.family)) { uint8_t data[4 + sizeof(IP4) + sizeof(uint16_t)]; - const int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port); + const TCP_Connection *con = &tcp_conn->con; + const int ret = read_TCP_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port); if (ret == -1) { return 0; @@ -273,7 +277,8 @@ static int proxy_socks5_read_connection_response(const Logger *logger, const TCP } } else { uint8_t data[4 + sizeof(IP6) + sizeof(uint16_t)]; - int ret = read_TCP_packet(logger, tcp_conn->con.ns, tcp_conn->con.sock, data, sizeof(data), &tcp_conn->con.ip_port); + const TCP_Connection *con = &tcp_conn->con; + int ret = read_TCP_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port); if (ret == -1) { return 0; @@ -566,10 +571,16 @@ void forwarding_handler(TCP_Client_Connection *con, forwarded_response_cb *forwa /** Create new TCP connection to ip_port/public_key */ TCP_Client_Connection *new_TCP_connection( - const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port, - const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, + const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, + const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, const TCP_Proxy_Info *proxy_info) { + assert(logger != nullptr); + assert(mem != nullptr); + assert(mono_time != nullptr); + assert(rng != nullptr); + assert(ns != nullptr); + if (!net_family_is_ipv4(ip_port->ip.family) && !net_family_is_ipv6(ip_port->ip.family)) { return nullptr; } @@ -597,12 +608,12 @@ TCP_Client_Connection *new_TCP_connection( return nullptr; } - if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, sock, ip_port, proxy_info))) { + if (!(set_socket_nonblock(ns, sock) && connect_sock_to(logger, mem, sock, ip_port, proxy_info))) { kill_sock(ns, sock); return nullptr; } - TCP_Client_Connection *temp = (TCP_Client_Connection *)calloc(1, sizeof(TCP_Client_Connection)); + TCP_Client_Connection *temp = (TCP_Client_Connection *)mem_alloc(mem, sizeof(TCP_Client_Connection)); if (temp == nullptr) { kill_sock(ns, sock); @@ -610,6 +621,7 @@ TCP_Client_Connection *new_TCP_connection( } temp->con.ns = ns; + temp->con.mem = mem; temp->con.rng = rng; temp->con.sock = sock; temp->con.ip_port = *ip_port; @@ -637,7 +649,7 @@ TCP_Client_Connection *new_TCP_connection( if (generate_handshake(temp) == -1) { kill_sock(ns, sock); - free(temp); + mem_delete(mem, temp); return nullptr; } @@ -852,7 +864,7 @@ non_null(1, 2) nullable(3) static bool tcp_process_packet(const Logger *logger, TCP_Client_Connection *conn, void *userdata) { uint8_t packet[MAX_PACKET_SIZE]; - const int len = read_packet_TCP_secure_connection(logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port); + const int len = read_packet_TCP_secure_connection(logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->ip_port); if (len == 0) { return false; @@ -969,7 +981,8 @@ void do_TCP_connection(const Logger *logger, const Mono_Time *mono_time, if (tcp_connection->status == TCP_CLIENT_UNCONFIRMED) { uint8_t data[TCP_SERVER_HANDSHAKE_SIZE]; - const int len = read_TCP_packet(logger, tcp_connection->con.ns, tcp_connection->con.sock, data, sizeof(data), &tcp_connection->con.ip_port); + const TCP_Connection *con = &tcp_connection->con; + const int len = read_TCP_packet(logger, con->mem, con->ns, con->sock, data, sizeof(data), &con->ip_port); if (sizeof(data) == len) { if (handle_handshake(tcp_connection, data) == 0) { @@ -998,8 +1011,10 @@ void kill_TCP_connection(TCP_Client_Connection *tcp_connection) return; } - wipe_priority_list(tcp_connection->con.priority_queue_start); + const Memory *mem = tcp_connection->con.mem; + + wipe_priority_list(tcp_connection->con.mem, tcp_connection->con.priority_queue_start); kill_sock(tcp_connection->con.ns, tcp_connection->con.sock); crypto_memzero(tcp_connection, sizeof(TCP_Client_Connection)); - free(tcp_connection); + mem_delete(mem, tcp_connection); } diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index fdc91de70d..b020aaad91 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -57,10 +57,10 @@ non_null() void tcp_con_set_custom_uint(TCP_Client_Connection *con, uint32_t value); /** Create new TCP connection to ip_port/public_key */ -non_null(1, 2, 3, 4, 5, 6, 7, 8) nullable(9) +non_null(1, 2, 3, 4, 5, 6, 7, 8, 9) nullable(10) TCP_Client_Connection *new_TCP_connection( - const Logger *logger, const Mono_Time *mono_time, const Random *rng, const Network *ns, const IP_Port *ip_port, - const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, + const Logger *logger, const Memory *mem, const Mono_Time *mono_time, const Random *rng, const Network *ns, + const IP_Port *ip_port, const uint8_t *public_key, const uint8_t *self_public_key, const uint8_t *self_secret_key, const TCP_Proxy_Info *proxy_info); /** Run the TCP connection */ diff --git a/toxcore/TCP_common.c b/toxcore/TCP_common.c index a42faced1a..36a751f386 100644 --- a/toxcore/TCP_common.c +++ b/toxcore/TCP_common.c @@ -10,13 +10,13 @@ #include "ccompat.h" -void wipe_priority_list(TCP_Priority_List *p) +void wipe_priority_list(const Memory *mem, TCP_Priority_List *p) { while (p != nullptr) { TCP_Priority_List *pp = p; p = p->next; - free(pp->data); - free(pp); + mem_delete(mem, pp->data); + mem_delete(mem, pp); } } @@ -74,8 +74,8 @@ int send_pending_data(const Logger *logger, TCP_Connection *con) TCP_Priority_List *pp = p; p = p->next; - free(pp->data); - free(pp); + mem_delete(con->mem, pp->data); + mem_delete(con->mem, pp); } con->priority_queue_start = p; @@ -89,14 +89,14 @@ int send_pending_data(const Logger *logger, TCP_Connection *con) } /** - * @retval false on failure (only if calloc fails) + * @retval false on failure (only if mem_alloc fails) * @retval true on success */ non_null() static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent) { TCP_Priority_List *p = con->priority_queue_end; - TCP_Priority_List *new_list = (TCP_Priority_List *)calloc(1, sizeof(TCP_Priority_List)); + TCP_Priority_List *new_list = (TCP_Priority_List *)mem_alloc(con->mem, sizeof(TCP_Priority_List)); if (new_list == nullptr) { return false; @@ -105,10 +105,10 @@ static bool add_priority(TCP_Connection *con, const uint8_t *packet, uint16_t si new_list->next = nullptr; new_list->size = size; new_list->sent = sent; - new_list->data = (uint8_t *)malloc(size); + new_list->data = (uint8_t *)mem_balloc(con->mem, size); if (new_list->data == nullptr) { - free(new_list); + mem_delete(con->mem, new_list); return false; } @@ -195,7 +195,8 @@ int write_packet_TCP_secure_connection(const Logger *logger, TCP_Connection *con * return length on success * return -1 on failure/no data in buffer. */ -int read_TCP_packet(const Logger *logger, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port) +int read_TCP_packet( + const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port) { const uint16_t count = net_socket_data_recv_buffer(ns, sock); @@ -222,7 +223,7 @@ int read_TCP_packet(const Logger *logger, const Network *ns, Socket sock, uint8_ * return -1 on failure. */ non_null() -static uint16_t read_TCP_length(const Logger *logger, const Network *ns, Socket sock, const IP_Port *ip_port) +static uint16_t read_TCP_length(const Logger *logger, const Memory *mem, const Network *ns, Socket sock, const IP_Port *ip_port) { const uint16_t count = net_socket_data_recv_buffer(ns, sock); @@ -255,12 +256,13 @@ static uint16_t read_TCP_length(const Logger *logger, const Network *ns, Socket * @retval -1 on failure (connection must be killed). */ int read_packet_TCP_secure_connection( - const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length, + const Logger *logger, const Memory *mem, const Network *ns, + Socket sock, uint16_t *next_packet_length, const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len, const IP_Port *ip_port) { if (*next_packet_length == 0) { - const uint16_t len = read_TCP_length(logger, ns, sock, ip_port); + const uint16_t len = read_TCP_length(logger, mem, ns, sock, ip_port); if (len == (uint16_t) -1) { return -1; @@ -279,7 +281,7 @@ int read_packet_TCP_secure_connection( } VLA(uint8_t, data_encrypted, (int) *next_packet_length); - const int len_packet = read_TCP_packet(logger, ns, sock, data_encrypted, *next_packet_length, ip_port); + const int len_packet = read_TCP_packet(logger, mem, ns, sock, data_encrypted, *next_packet_length, ip_port); if (len_packet == -1) { return 0; diff --git a/toxcore/TCP_common.h b/toxcore/TCP_common.h index 78d1623d8a..44dc2e71e0 100644 --- a/toxcore/TCP_common.h +++ b/toxcore/TCP_common.h @@ -7,6 +7,7 @@ #define C_TOXCORE_TOXCORE_TCP_COMMON_H #include "crypto_core.h" +#include "mem.h" #include "network.h" typedef struct TCP_Priority_List TCP_Priority_List; @@ -17,8 +18,8 @@ struct TCP_Priority_List { uint8_t *data; }; -nullable(1) -void wipe_priority_list(TCP_Priority_List *p); +non_null(1) nullable(2) +void wipe_priority_list(const Memory *mem, TCP_Priority_List *p); #define NUM_RESERVED_PORTS 16 #define NUM_CLIENT_CONNECTIONS (256 - NUM_RESERVED_PORTS) @@ -63,6 +64,7 @@ void wipe_priority_list(TCP_Priority_List *p); #define MAX_PACKET_SIZE 2048 typedef struct TCP_Connection { + const Memory *mem; const Random *rng; const Network *ns; Socket sock; @@ -108,7 +110,7 @@ int write_packet_TCP_secure_connection( */ non_null() int read_TCP_packet( - const Logger *logger, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port); + const Logger *logger, const Memory *mem, const Network *ns, Socket sock, uint8_t *data, uint16_t length, const IP_Port *ip_port); /** * @return length of received packet on success. @@ -117,7 +119,8 @@ int read_TCP_packet( */ non_null() int read_packet_TCP_secure_connection( - const Logger *logger, const Network *ns, Socket sock, uint16_t *next_packet_length, + const Logger *logger, const Memory *mem, const Network *ns, + Socket sock, uint16_t *next_packet_length, const uint8_t *shared_key, uint8_t *recv_nonce, uint8_t *data, uint16_t max_len, const IP_Port *ip_port); diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c index 4c71f366b3..2c75e74ea5 100644 --- a/toxcore/TCP_connection.c +++ b/toxcore/TCP_connection.c @@ -19,6 +19,7 @@ struct TCP_Connections { const Logger *logger; + const Memory *mem; const Random *rng; Mono_Time *mono_time; const Network *ns; @@ -69,20 +70,20 @@ uint32_t tcp_connections_count(const TCP_Connections *tcp_c) /** @brief Set the size of the array to num. * - * @retval -1 if realloc fails. + * @retval -1 if mem_vrealloc fails. * @retval 0 if it succeeds. */ non_null() -static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num) +static int realloc_TCP_Connection_to(const Memory *mem, TCP_Connection_to **array, size_t num) { if (num == 0) { - free(*array); + mem_delete(mem, *array); *array = nullptr; return 0; } TCP_Connection_to *temp_pointer = - (TCP_Connection_to *)realloc(*array, num * sizeof(TCP_Connection_to)); + (TCP_Connection_to *)mem_vrealloc(mem, *array, num, sizeof(TCP_Connection_to)); if (temp_pointer == nullptr) { return -1; @@ -94,15 +95,15 @@ static int realloc_TCP_Connection_to(TCP_Connection_to **array, size_t num) } non_null() -static int realloc_TCP_con(TCP_con **array, size_t num) +static int realloc_TCP_con(const Memory *mem, TCP_con **array, size_t num) { if (num == 0) { - free(*array); + mem_delete(mem, *array); *array = nullptr; return 0; } - TCP_con *temp_pointer = (TCP_con *)realloc(*array, num * sizeof(TCP_con)); + TCP_con *temp_pointer = (TCP_con *)mem_vrealloc(mem, *array, num, sizeof(TCP_con)); if (temp_pointer == nullptr) { return -1; @@ -164,7 +165,7 @@ static int create_connection(TCP_Connections *tcp_c) int id = -1; - if (realloc_TCP_Connection_to(&tcp_c->connections, tcp_c->connections_length + 1) == 0) { + if (realloc_TCP_Connection_to(tcp_c->mem, &tcp_c->connections, tcp_c->connections_length + 1) == 0) { id = tcp_c->connections_length; ++tcp_c->connections_length; tcp_c->connections[id] = empty_tcp_connection_to; @@ -189,7 +190,7 @@ static int create_tcp_connection(TCP_Connections *tcp_c) int id = -1; - if (realloc_TCP_con(&tcp_c->tcp_connections, tcp_c->tcp_connections_length + 1) == 0) { + if (realloc_TCP_con(tcp_c->mem, &tcp_c->tcp_connections, tcp_c->tcp_connections_length + 1) == 0) { id = tcp_c->tcp_connections_length; ++tcp_c->tcp_connections_length; tcp_c->tcp_connections[id] = empty_tcp_con; @@ -221,7 +222,9 @@ static int wipe_connection(TCP_Connections *tcp_c, int connections_number) if (tcp_c->connections_length != i) { tcp_c->connections_length = i; - realloc_TCP_Connection_to(&tcp_c->connections, tcp_c->connections_length); + if (realloc_TCP_Connection_to(tcp_c->mem, &tcp_c->connections, tcp_c->connections_length) != 0) { + return -1; + } } return 0; @@ -251,7 +254,9 @@ static int wipe_tcp_connection(TCP_Connections *tcp_c, int tcp_connections_numbe if (tcp_c->tcp_connections_length != i) { tcp_c->tcp_connections_length = i; - realloc_TCP_con(&tcp_c->tcp_connections, tcp_c->tcp_connections_length); + if (realloc_TCP_con(tcp_c->mem, &tcp_c->tcp_connections, tcp_c->tcp_connections_length) != 0) { + return -1; + } } return 0; @@ -920,7 +925,7 @@ static int reconnect_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connec uint8_t relay_pk[CRYPTO_PUBLIC_KEY_SIZE]; memcpy(relay_pk, tcp_con_public_key(tcp_con->connection), CRYPTO_PUBLIC_KEY_SIZE); kill_TCP_connection(tcp_con->connection); - tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); + tcp_con->connection = new_TCP_connection(tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ip_port, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { kill_tcp_relay_connection(tcp_c, tcp_connections_number); @@ -1008,7 +1013,7 @@ static int unsleep_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connecti } tcp_con->connection = new_TCP_connection( - tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, + tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &tcp_con->ip_port, tcp_con->relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { @@ -1304,7 +1309,7 @@ static int add_tcp_relay_instance(TCP_Connections *tcp_c, const IP_Port *ip_port TCP_con *tcp_con = &tcp_c->tcp_connections[tcp_connections_number]; tcp_con->connection = new_TCP_connection( - tcp_c->logger, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, + tcp_c->logger, tcp_c->mem, tcp_c->mono_time, tcp_c->rng, tcp_c->ns, &ipp_copy, relay_pk, tcp_c->self_public_key, tcp_c->self_secret_key, &tcp_c->proxy_info); if (tcp_con->connection == nullptr) { @@ -1580,21 +1585,27 @@ int set_tcp_onion_status(TCP_Connections *tcp_c, bool status) * * Returns NULL on failure. */ -TCP_Connections *new_tcp_connections( - const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, const uint8_t *secret_key, - const TCP_Proxy_Info *proxy_info) +TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, + Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info) { + assert(logger != nullptr); + assert(mem != nullptr); + assert(rng != nullptr); + assert(ns != nullptr); + assert(mono_time != nullptr); + if (secret_key == nullptr) { return nullptr; } - TCP_Connections *temp = (TCP_Connections *)calloc(1, sizeof(TCP_Connections)); + TCP_Connections *temp = (TCP_Connections *)mem_alloc(mem, sizeof(TCP_Connections)); if (temp == nullptr) { return nullptr; } temp->logger = logger; + temp->mem = mem; temp->rng = rng; temp->mono_time = mono_time; temp->ns = ns; @@ -1707,7 +1718,7 @@ void kill_tcp_connections(TCP_Connections *tcp_c) crypto_memzero(tcp_c->self_secret_key, sizeof(tcp_c->self_secret_key)); - free(tcp_c->tcp_connections); - free(tcp_c->connections); - free(tcp_c); + mem_delete(tcp_c->mem, tcp_c->tcp_connections); + mem_delete(tcp_c->mem, tcp_c->connections); + mem_delete(tcp_c->mem, tcp_c); } diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index 0434a73eb0..f01e705445 100644 --- a/toxcore/TCP_connection.h +++ b/toxcore/TCP_connection.h @@ -298,9 +298,8 @@ uint32_t tcp_copy_connected_relays_index(const TCP_Connections *tcp_c, Node_form * Returns NULL on failure. */ non_null() -TCP_Connections *new_tcp_connections( - const Logger *logger, const Random *rng, const Network *ns, Mono_Time *mono_time, - const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info); +TCP_Connections *new_tcp_connections(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, + Mono_Time *mono_time, const uint8_t *secret_key, const TCP_Proxy_Info *proxy_info); non_null() int kill_tcp_relay_connection(TCP_Connections *tcp_c, int tcp_connections_number); diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index ecd557d1b2..80a1f0165a 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -58,6 +58,7 @@ typedef struct TCP_Secure_Connection { struct TCP_Server { const Logger *logger; + const Memory *mem; const Random *rng; const Network *ns; Onion *onion; @@ -117,9 +118,9 @@ static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num) return -1; } - TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc( - tcp_server->accepted_connection_array, - new_size * sizeof(TCP_Secure_Connection)); + TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)mem_vrealloc( + tcp_server->mem, tcp_server->accepted_connection_array, + new_size, sizeof(TCP_Secure_Connection)); if (new_connections == nullptr) { return -1; @@ -138,7 +139,7 @@ non_null() static void wipe_secure_connection(TCP_Secure_Connection *con) { if (con->status != 0) { - wipe_priority_list(con->con.priority_queue_start); + wipe_priority_list(con->con.mem, con->con.priority_queue_start); crypto_memzero(con, sizeof(TCP_Secure_Connection)); } } @@ -161,7 +162,7 @@ static void free_accepted_connection_array(TCP_Server *tcp_server) wipe_secure_connection(&tcp_server->accepted_connection_array[i]); } - free(tcp_server->accepted_connection_array); + mem_delete(tcp_server->mem, tcp_server->accepted_connection_array); tcp_server->accepted_connection_array = nullptr; tcp_server->size_accepted_connections = 0; } @@ -369,7 +370,7 @@ non_null() static int read_connection_handshake(const Logger *logger, TCP_Secure_Connection *con, const uint8_t *self_secret_key) { uint8_t data[TCP_CLIENT_HANDSHAKE_SIZE]; - const int len = read_TCP_packet(logger, con->con.ns, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port); + const int len = read_TCP_packet(logger, con->con.mem, con->con.ns, con->con.sock, data, TCP_CLIENT_HANDSHAKE_SIZE, &con->con.ip_port); if (len == -1) { LOGGER_TRACE(logger, "connection handshake is not ready yet"); @@ -892,6 +893,7 @@ static int accept_connection(TCP_Server *tcp_server, Socket sock) conn->status = TCP_STATUS_CONNECTED; conn->con.ns = tcp_server->ns; + conn->con.mem = tcp_server->mem; conn->con.rng = tcp_server->rng; conn->con.sock = sock; conn->next_packet_length = 0; @@ -935,7 +937,7 @@ static Socket new_listening_TCP_socket(const Logger *logger, const Network *ns, return sock; } -TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns, +TCP_Server *new_TCP_server(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports, const uint8_t *secret_key, Onion *onion, Forwarding *forwarding) { @@ -949,7 +951,7 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ return nullptr; } - TCP_Server *temp = (TCP_Server *)calloc(1, sizeof(TCP_Server)); + TCP_Server *temp = (TCP_Server *)mem_alloc(mem, sizeof(TCP_Server)); if (temp == nullptr) { LOGGER_ERROR(logger, "TCP server allocation failed"); @@ -957,14 +959,15 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ } temp->logger = logger; + temp->mem = mem; temp->ns = ns; temp->rng = rng; - temp->socks_listening = (Socket *)calloc(num_sockets, sizeof(Socket)); + temp->socks_listening = (Socket *)mem_valloc(mem, num_sockets, sizeof(Socket)); if (temp->socks_listening == nullptr) { LOGGER_ERROR(logger, "socket allocation failed"); - free(temp); + mem_delete(mem, temp); return nullptr; } @@ -973,8 +976,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ if (temp->efd == -1) { LOGGER_ERROR(logger, "epoll initialisation failed"); - free(temp->socks_listening); - free(temp); + mem_delete(mem, temp->socks_listening); + mem_delete(mem, temp); return nullptr; } @@ -1006,8 +1009,8 @@ TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Networ } if (temp->num_listening_socks == 0) { - free(temp->socks_listening); - free(temp); + mem_delete(mem, temp->socks_listening); + mem_delete(mem, temp); return nullptr; } @@ -1096,7 +1099,7 @@ static int do_unconfirmed(TCP_Server *tcp_server, const Mono_Time *mono_time, ui LOGGER_TRACE(tcp_server->logger, "handling unconfirmed TCP connection %d", i); uint8_t packet[MAX_PACKET_SIZE]; - const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); + const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); if (len == 0) { return -1; @@ -1116,7 +1119,7 @@ static bool tcp_process_secure_packet(TCP_Server *tcp_server, uint32_t i) TCP_Secure_Connection *const conn = &tcp_server->accepted_connection_array[i]; uint8_t packet[MAX_PACKET_SIZE]; - const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); + const int len = read_packet_TCP_secure_connection(tcp_server->logger, conn->con.mem, conn->con.ns, conn->con.sock, &conn->next_packet_length, conn->con.shared_key, conn->recv_nonce, packet, sizeof(packet), &conn->con.ip_port); LOGGER_TRACE(tcp_server->logger, "processing packet for %d: %d", i, len); if (len == 0) { @@ -1406,6 +1409,6 @@ void kill_TCP_server(TCP_Server *tcp_server) crypto_memzero(tcp_server->secret_key, sizeof(tcp_server->secret_key)); - free(tcp_server->socks_listening); - free(tcp_server); + mem_delete(tcp_server->mem, tcp_server->socks_listening); + mem_delete(tcp_server->mem, tcp_server); } diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h index 2224938a09..090e821607 100644 --- a/toxcore/TCP_server.h +++ b/toxcore/TCP_server.h @@ -34,8 +34,8 @@ non_null() size_t tcp_server_listen_count(const TCP_Server *tcp_server); /** Create new TCP server instance. */ -non_null(1, 2, 3, 6, 7) nullable(8, 9) -TCP_Server *new_TCP_server(const Logger *logger, const Random *rng, const Network *ns, +non_null(1, 2, 3, 4, 7, 8) nullable(9, 10) +TCP_Server *new_TCP_server(const Logger *logger, const Memory *mem, const Random *rng, const Network *ns, bool ipv6_enabled, uint16_t num_sockets, const uint16_t *ports, const uint8_t *secret_key, Onion *onion, Forwarding *forwarding); diff --git a/toxcore/announce.c b/toxcore/announce.c index 647bd21ea3..fbbb2350c6 100644 --- a/toxcore/announce.c +++ b/toxcore/announce.c @@ -50,6 +50,7 @@ typedef struct Announce_Entry { struct Announcements { const Logger *log; + const Memory *mem; const Random *rng; Forwarding *forwarding; const Mono_Time *mono_time; @@ -593,8 +594,8 @@ static int create_reply(Announcements *announce, const IP_Port *source, const uint8_t response_type = announce_response_of_request_type(data[0]); - return dht_create_packet(announce->rng, announce->public_key, shared_key, response_type, - plain_reply, plain_reply_len, reply, reply_max_length); + return dht_create_packet(announce->mem, announce->rng, announce->public_key, shared_key, + response_type, plain_reply, plain_reply_len, reply, reply_max_length); } non_null(1, 2, 3, 5) nullable(7) @@ -636,7 +637,7 @@ static int handle_dht_announce_request(void *object, const IP_Port *source, return sendpacket(announce->net, source, reply, len) == len ? 0 : -1; } -Announcements *new_announcements(const Logger *log, const Random *rng, const Mono_Time *mono_time, +Announcements *new_announcements(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Forwarding *forwarding) { if (log == nullptr || mono_time == nullptr || forwarding == nullptr) { @@ -650,6 +651,7 @@ Announcements *new_announcements(const Logger *log, const Random *rng, const Mon } announce->log = log; + announce->mem = mem; announce->rng = rng; announce->forwarding = forwarding; announce->mono_time = mono_time; @@ -658,7 +660,7 @@ Announcements *new_announcements(const Logger *log, const Random *rng, const Mon announce->public_key = dht_get_self_public_key(announce->dht); announce->secret_key = dht_get_self_secret_key(announce->dht); new_hmac_key(announce->rng, announce->hmac_key); - announce->shared_keys = shared_key_cache_new(mono_time, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + announce->shared_keys = shared_key_cache_new(mono_time, mem, announce->secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (announce->shared_keys == nullptr) { free(announce); return nullptr; diff --git a/toxcore/announce.h b/toxcore/announce.h index e680da68b6..bbd7a72b45 100644 --- a/toxcore/announce.h +++ b/toxcore/announce.h @@ -16,7 +16,8 @@ uint8_t announce_response_of_request_type(uint8_t request_type); typedef struct Announcements Announcements; non_null() -Announcements *new_announcements(const Logger *log, const Random *rng, const Mono_Time *mono_time, Forwarding *forwarding); +Announcements *new_announcements(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, + Forwarding *forwarding); /** * @brief If data is stored, run `on_retrieve_callback` on it. diff --git a/toxcore/forwarding_fuzz_test.cc b/toxcore/forwarding_fuzz_test.cc index 2abd245dd4..ce263f1e6f 100644 --- a/toxcore/forwarding_fuzz_test.cc +++ b/toxcore/forwarding_fuzz_test.cc @@ -12,8 +12,10 @@ void TestSendForwardRequest(Fuzz_Data &input) { const Network *ns = system_network(); // TODO(iphydf): fuzz_network assert(ns != nullptr); + const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory + assert(mem != nullptr); - with{} >> with{input, ns} >> [&input](Ptr net) { + with{} >> with{input, ns, mem} >> [&input](Ptr net) { with{input} >> [net = std::move(net), &input](const IP_Port &forwarder) { CONSUME1_OR_RETURN(const uint16_t chain_length, input); const uint16_t chain_keys_size = chain_length * CRYPTO_PUBLIC_KEY_SIZE; @@ -29,8 +31,10 @@ void TestForwardReply(Fuzz_Data &input) { const Network *ns = system_network(); // TODO(iphydf): fuzz_network assert(ns != nullptr); + const Memory *mem = system_memory(); // TODO(iphydf): fuzz_memory + assert(mem != nullptr); - with{} >> with{input, ns} >> [&input](Ptr net) { + with{} >> with{input, ns, mem} >> [&input](Ptr net) { with{input} >> [net = std::move(net), &input](const IP_Port &forwarder) { CONSUME1_OR_RETURN(const uint16_t sendback_length, input); CONSUME_OR_RETURN(const uint8_t *sendback, input, sendback_length); diff --git a/toxcore/group_announce_fuzz_test.cc b/toxcore/group_announce_fuzz_test.cc index c090176c35..6728e71284 100644 --- a/toxcore/group_announce_fuzz_test.cc +++ b/toxcore/group_announce_fuzz_test.cc @@ -1,6 +1,7 @@ #include "group_announce.h" #include +#include #include #include @@ -44,9 +45,10 @@ void TestUnpackPublicAnnounce(Fuzz_Data &input) void TestDoGca(Fuzz_Data &input) { + const Memory *mem = system_memory(); std::unique_ptr logger(logger_new(), logger_kill); - std::unique_ptr mono_time( - mono_time_new(nullptr, nullptr), mono_time_free); + std::unique_ptr> mono_time( + mono_time_new(mem, nullptr, nullptr), [mem](Mono_Time *ptr) { mono_time_free(mem, ptr); }); assert(mono_time != nullptr); uint64_t clock = 1; mono_time_set_current_time_callback( diff --git a/toxcore/group_announce_test.cc b/toxcore/group_announce_test.cc index eca1da2bd7..d3d5d71581 100644 --- a/toxcore/group_announce_test.cc +++ b/toxcore/group_announce_test.cc @@ -8,6 +8,7 @@ namespace { struct Announces : ::testing::Test { protected: + const Memory *mem_ = system_memory(); uint64_t clock_ = 0; Mono_Time *mono_time_ = nullptr; GC_Announces_List *gca_ = nullptr; @@ -16,7 +17,7 @@ struct Announces : ::testing::Test { void SetUp() override { - mono_time_ = mono_time_new(nullptr, nullptr); + mono_time_ = mono_time_new(mem_, nullptr, nullptr); ASSERT_NE(mono_time_, nullptr); mono_time_set_current_time_callback( mono_time_, [](void *user_data) { return *static_cast(user_data); }, @@ -28,7 +29,7 @@ struct Announces : ::testing::Test { ~Announces() override { kill_gca(gca_); - mono_time_free(mono_time_); + mono_time_free(mem_, mono_time_); } void advance_clock(uint64_t increment) diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index f9cb2d18fb..a18ba1494c 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -7250,7 +7250,7 @@ static bool init_gc_tcp_connection(const GC_Session *c, GC_Chat *chat) { const Messenger *m = c->messenger; - chat->tcp_conn = new_tcp_connections(chat->log, chat->rng, m->ns, chat->mono_time, chat->self_secret_key, + chat->tcp_conn = new_tcp_connections(chat->log, chat->mem, chat->rng, m->ns, chat->mono_time, chat->self_secret_key, &m->options.proxy_info); if (chat->tcp_conn == nullptr) { @@ -7305,6 +7305,7 @@ static void init_gc_moderation(GC_Chat *chat) memcpy(chat->moderation.self_secret_sig_key, get_sig_pk(chat->self_secret_key), SIG_SECRET_KEY_SIZE); chat->moderation.shared_state_version = chat->shared_state.version; chat->moderation.log = chat->log; + chat->moderation.mem = chat->mem; } non_null() @@ -7332,6 +7333,7 @@ static int create_new_group(GC_Session *c, const uint8_t *nick, size_t nick_leng GC_Chat *chat = &c->chats[group_number]; chat->log = m->log; + chat->mem = m->mem; chat->rng = m->rng; const uint64_t tm = mono_time_get(m->mono_time); @@ -7476,6 +7478,7 @@ int gc_group_load(GC_Session *c, Bin_Unpack *bu) chat->net = m->net; chat->mono_time = m->mono_time; chat->log = m->log; + chat->mem = m->mem; chat->rng = m->rng; chat->last_ping_interval = tm; chat->friend_connection_id = -1; diff --git a/toxcore/group_common.h b/toxcore/group_common.h index ef901e8a3a..34d67dc8d6 100644 --- a/toxcore/group_common.h +++ b/toxcore/group_common.h @@ -247,6 +247,7 @@ typedef struct GC_TopicInfo { typedef struct GC_Chat { Mono_Time *mono_time; const Logger *log; + const Memory *mem; const Random *rng; uint32_t connected_tcp_relays; diff --git a/toxcore/group_moderation.c b/toxcore/group_moderation.c index b16c397cbe..eeed26d00e 100644 --- a/toxcore/group_moderation.c +++ b/toxcore/group_moderation.c @@ -61,7 +61,7 @@ int mod_list_unpack(Moderation *moderation, const uint8_t *data, uint16_t length tmp_list[i] = (uint8_t *)malloc(sizeof(uint8_t) * MOD_LIST_ENTRY_SIZE); if (tmp_list[i] == nullptr) { - free_uint8_t_pointer_array(tmp_list, i); + free_uint8_t_pointer_array(moderation->mem, tmp_list, i); return -1; } @@ -221,7 +221,7 @@ bool mod_list_add_entry(Moderation *moderation, const uint8_t *mod_data) void mod_list_cleanup(Moderation *moderation) { - free_uint8_t_pointer_array(moderation->mod_list, moderation->num_mods); + free_uint8_t_pointer_array(moderation->mem, moderation->mod_list, moderation->num_mods); moderation->num_mods = 0; moderation->mod_list = nullptr; } diff --git a/toxcore/group_moderation.h b/toxcore/group_moderation.h index 8b2a73869a..c57e0a81cf 100644 --- a/toxcore/group_moderation.h +++ b/toxcore/group_moderation.h @@ -78,6 +78,7 @@ typedef struct Mod_Sanction { } Mod_Sanction; typedef struct Moderation { + const Memory *mem; const Logger *log; Mod_Sanction *sanctions; diff --git a/toxcore/group_moderation_fuzz_test.cc b/toxcore/group_moderation_fuzz_test.cc index 8b503c1597..c5f46f3417 100644 --- a/toxcore/group_moderation_fuzz_test.cc +++ b/toxcore/group_moderation_fuzz_test.cc @@ -7,7 +7,7 @@ namespace { void TestModListUnpack(Fuzz_Data &input) { CONSUME1_OR_RETURN(const uint16_t num_mods, input); - Moderation mods{}; + Moderation mods{system_memory()}; mod_list_unpack(&mods, input.data, input.size, num_mods); mod_list_cleanup(&mods); } diff --git a/toxcore/group_moderation_test.cc b/toxcore/group_moderation_test.cc index e632c3cc8f..e55122896a 100644 --- a/toxcore/group_moderation_test.cc +++ b/toxcore/group_moderation_test.cc @@ -18,7 +18,7 @@ using ModerationHash = std::array; TEST(ModList, PackedSizeOfEmptyModListIsZero) { - Moderation mods{}; + Moderation mods{system_memory()}; EXPECT_EQ(mod_list_packed_size(&mods), 0); uint8_t byte = 1; @@ -28,14 +28,14 @@ TEST(ModList, PackedSizeOfEmptyModListIsZero) TEST(ModList, UnpackingZeroSizeArrayIsNoop) { - Moderation mods{}; + Moderation mods{system_memory()}; const uint8_t byte = 1; EXPECT_EQ(mod_list_unpack(&mods, &byte, 0, 0), 0); } TEST(ModList, AddRemoveMultipleMods) { - Moderation mods{}; + Moderation mods{system_memory()}; uint8_t sig_pk1[32] = {1}; uint8_t sig_pk2[32] = {2}; EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk1)); @@ -47,7 +47,7 @@ TEST(ModList, AddRemoveMultipleMods) TEST(ModList, PackingAndUnpackingList) { using ModListEntry = std::array; - Moderation mods{}; + Moderation mods{system_memory()}; EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data())); std::vector packed(mod_list_packed_size(&mods)); @@ -55,7 +55,7 @@ TEST(ModList, PackingAndUnpackingList) EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data())); - Moderation mods2{}; + Moderation mods2{system_memory()}; EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 1), packed.size()); EXPECT_TRUE(mod_list_remove_entry(&mods2, ModListEntry{}.data())); } @@ -63,13 +63,13 @@ TEST(ModList, PackingAndUnpackingList) TEST(ModList, UnpackingTooManyModsFails) { using ModListEntry = std::array; - Moderation mods{}; + Moderation mods{system_memory()}; EXPECT_TRUE(mod_list_add_entry(&mods, ModListEntry{}.data())); std::vector packed(mod_list_packed_size(&mods)); mod_list_pack(&mods, packed.data()); - Moderation mods2{}; + Moderation mods2{system_memory()}; EXPECT_EQ(mod_list_unpack(&mods2, packed.data(), packed.size(), 2), -1); EXPECT_TRUE(mod_list_remove_entry(&mods, ModListEntry{}.data())); } @@ -78,7 +78,7 @@ TEST(ModList, UnpackingFromEmptyBufferFails) { std::vector packed(1); - Moderation mods{}; + Moderation mods{system_memory()}; EXPECT_EQ(mod_list_unpack(&mods, packed.end().base(), 0, 1), -1); } @@ -87,7 +87,7 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer) const Random *rng = system_random(); ASSERT_NE(rng, nullptr); - Moderation mods{}; + Moderation mods{system_memory()}; // Fill with random data, check that it's zeroed. ModerationHash hash; @@ -98,21 +98,21 @@ TEST(ModList, HashOfEmptyModListZeroesOutBuffer) TEST(ModList, RemoveIndexFromEmptyModListFails) { - Moderation mods{}; + Moderation mods{system_memory()}; EXPECT_FALSE(mod_list_remove_index(&mods, 0)); EXPECT_FALSE(mod_list_remove_index(&mods, UINT16_MAX)); } TEST(ModList, RemoveEntryFromEmptyModListFails) { - Moderation mods{}; + Moderation mods{system_memory()}; uint8_t sig_pk[32] = {0}; EXPECT_FALSE(mod_list_remove_entry(&mods, sig_pk)); } TEST(ModList, ModListRemoveIndex) { - Moderation mods{}; + Moderation mods{system_memory()}; uint8_t sig_pk[32] = {1}; EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_remove_index(&mods, 0)); @@ -120,20 +120,20 @@ TEST(ModList, ModListRemoveIndex) TEST(ModList, CleanupOnEmptyModsIsNoop) { - Moderation mods{}; + Moderation mods{system_memory()}; mod_list_cleanup(&mods); } TEST(ModList, EmptyModListCannotVerifyAnySigPk) { - Moderation mods{}; + Moderation mods{system_memory()}; uint8_t sig_pk[32] = {1}; EXPECT_FALSE(mod_list_verify_sig_pk(&mods, sig_pk)); } TEST(ModList, ModListAddVerifyRemoveSigPK) { - Moderation mods{}; + Moderation mods{system_memory()}; uint8_t sig_pk[32] = {1}; EXPECT_TRUE(mod_list_add_entry(&mods, sig_pk)); EXPECT_TRUE(mod_list_verify_sig_pk(&mods, sig_pk)); @@ -143,7 +143,7 @@ TEST(ModList, ModListAddVerifyRemoveSigPK) TEST(ModList, ModListHashCheck) { - Moderation mods1{}; + Moderation mods1{system_memory()}; uint8_t sig_pk1[32] = {1}; std::array hash1; @@ -165,7 +165,7 @@ TEST(SanctionsList, PackingIntoUndersizedBufferFails) TEST(SanctionsList, PackUnpackSanctionsCreds) { - Moderation mod{}; + Moderation mod{system_memory()}; std::array packed; EXPECT_EQ(sanctions_creds_pack(&mod.sanctions_creds, packed.data()), MOD_SANCTIONS_CREDS_SIZE); EXPECT_EQ( @@ -177,7 +177,7 @@ struct SanctionsListMod : ::testing::Test { ExtPublicKey pk; ExtSecretKey sk; Logger *log = logger_new(); - Moderation mod{}; + Moderation mod{system_memory()}; Mod_Sanction sanctions[2] = {}; const uint8_t sanctioned_pk1[32] = {1}; diff --git a/toxcore/mem.c b/toxcore/mem.c new file mode 100644 index 0000000000..a15b9728df --- /dev/null +++ b/toxcore/mem.c @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#include "mem.h" + +#include + +#include "ccompat.h" + +nullable(1) +static void *sys_malloc(void *obj, uint32_t size) +{ + return malloc(size); +} + +nullable(1) +static void *sys_calloc(void *obj, uint32_t nmemb, uint32_t size) +{ + return calloc(nmemb, size); +} + +nullable(1, 2) +static void *sys_realloc(void *obj, void *ptr, uint32_t size) +{ + return realloc(ptr, size); +} + +nullable(1, 2) +static void sys_free(void *obj, void *ptr) +{ + free(ptr); +} + +static const Memory_Funcs system_memory_funcs = { + sys_malloc, + sys_calloc, + sys_realloc, + sys_free, +}; +static const Memory system_memory_obj = {&system_memory_funcs}; + +const Memory *system_memory(void) +{ + return &system_memory_obj; +} + +void *mem_balloc(const Memory *mem, uint32_t size) +{ + void *const ptr = mem->funcs->malloc(mem->obj, size); + return ptr; +} + +void *mem_alloc(const Memory *mem, uint32_t size) +{ + void *const ptr = mem->funcs->calloc(mem->obj, 1, size); + return ptr; +} + +void *mem_valloc(const Memory *mem, uint32_t nmemb, uint32_t size) +{ + const uint32_t bytes = nmemb * size; + + if (size != 0 && bytes / size != nmemb) { + return nullptr; + } + + void *const ptr = mem->funcs->calloc(mem->obj, nmemb, size); + return ptr; +} + +void *mem_vrealloc(const Memory *mem, void *ptr, uint32_t nmemb, uint32_t size) +{ + const uint32_t bytes = nmemb * size; + + if (size != 0 && bytes / size != nmemb) { + return nullptr; + } + + void *const new_ptr = mem->funcs->realloc(mem->obj, ptr, bytes); + return new_ptr; +} + +void mem_delete(const Memory *mem, void *ptr) +{ + mem->funcs->free(mem->obj, ptr); +} diff --git a/toxcore/mem.h b/toxcore/mem.h new file mode 100644 index 0000000000..a9d9e1d2c9 --- /dev/null +++ b/toxcore/mem.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. + */ + +/** + * Memory allocation and deallocation functions. + */ +#ifndef C_TOXCORE_TOXCORE_MEM_H +#define C_TOXCORE_TOXCORE_MEM_H + +#include // uint*_t + +#include "attributes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *mem_malloc_cb(void *obj, uint32_t size); +typedef void *mem_calloc_cb(void *obj, uint32_t nmemb, uint32_t size); +typedef void *mem_realloc_cb(void *obj, void *ptr, uint32_t size); +typedef void mem_free_cb(void *obj, void *ptr); + +/** @brief Functions wrapping standard C memory allocation functions. */ +typedef struct Memory_Funcs { + mem_malloc_cb *malloc; + mem_calloc_cb *calloc; + mem_realloc_cb *realloc; + mem_free_cb *free; +} Memory_Funcs; + +typedef struct Memory { + const Memory_Funcs *funcs; + void *obj; +} Memory; + +const Memory *system_memory(void); + +/** + * @brief Allocate an array of a given size for built-in types. + * + * The array will not be initialised. Supported built-in types are + * `uint8_t`, `int8_t`, and `int16_t`. + */ +non_null() void *mem_balloc(const Memory *mem, uint32_t size); + +/** + * @brief Allocate a single object. + * + * Always use as `(T *)mem_alloc(mem, sizeof(T))`. + */ +non_null() void *mem_alloc(const Memory *mem, uint32_t size); + +/** + * @brief Allocate a vector (array) of objects. + * + * Always use as `(T *)mem_valloc(mem, N, sizeof(T))`. + */ +non_null() void *mem_valloc(const Memory *mem, uint32_t nmemb, uint32_t size); + +/** + * @brief Resize an object vector. + * + * Changes the size of (and possibly moves) the memory block pointed to by + * @p ptr to be large enough for an array of @p nmemb elements, each of which + * is @p size bytes. It is similar to the call + * + * @code + * realloc(ptr, nmemb * size); + * @endcode + * + * However, unlike that `realloc()` call, `mem_vrealloc()` fails safely in the + * case where the multiplication would overflow. If such an overflow occurs, + * `mem_vrealloc()` returns `nullptr`. + */ +non_null(1) nullable(2) void *mem_vrealloc(const Memory *mem, void *ptr, uint32_t nmemb, uint32_t size); + +/** @brief Free an array, object, or object vector. */ +non_null(1) nullable(2) void mem_delete(const Memory *mem, void *ptr); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/toxcore/mem_test.cc b/toxcore/mem_test.cc new file mode 100644 index 0000000000..f787036616 --- /dev/null +++ b/toxcore/mem_test.cc @@ -0,0 +1,40 @@ +#include "mem.h" + +#include + +namespace { + +TEST(Mem, AllocLarge) +{ + // Mebi prefix: https://en.wikipedia.org/wiki/Binary_prefix. + constexpr uint32_t MI = 1024 * 1024; + + const Memory *mem = system_memory(); + + void *ptr = mem_valloc(mem, 4, MI); + EXPECT_NE(ptr, nullptr); + + mem_delete(mem, ptr); +} + +TEST(Mem, AllocOverflow) +{ + // Gibi prefix. + constexpr uint32_t GI = 1024 * 1024 * 1024; + + const Memory *mem = system_memory(); + + // 1 gibi-elements of 100 bytes each. + void *ptr = mem_valloc(mem, GI, 100); + EXPECT_EQ(ptr, nullptr); + + // 100 elements of 1 gibibyte each. + ptr = mem_valloc(mem, 100, GI); + EXPECT_EQ(ptr, nullptr); + + // 128 (a multiple of 2) elements of 1 gibibyte each. + ptr = mem_valloc(mem, 128, GI); + EXPECT_EQ(ptr, nullptr); +} + +} // namespace diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c index df64f2246c..e03046f799 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c @@ -122,25 +122,25 @@ static uint64_t current_time_monotonic_default(void *user_data) #endif // !OS_WIN32 -Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void *user_data) +Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data) { - Mono_Time *mono_time = (Mono_Time *)calloc(1, sizeof(Mono_Time)); + Mono_Time *mono_time = (Mono_Time *)mem_alloc(mem, sizeof(Mono_Time)); if (mono_time == nullptr) { return nullptr; } #ifndef ESP_PLATFORM - mono_time->time_update_lock = (pthread_rwlock_t *)calloc(1, sizeof(pthread_rwlock_t)); + mono_time->time_update_lock = (pthread_rwlock_t *)mem_alloc(mem, sizeof(pthread_rwlock_t)); if (mono_time->time_update_lock == nullptr) { - free(mono_time); + mem_delete(mem, mono_time); return nullptr; } if (pthread_rwlock_init(mono_time->time_update_lock, nullptr) < 0) { - free(mono_time->time_update_lock); - free(mono_time); + mem_delete(mem, mono_time->time_update_lock); + mem_delete(mem, mono_time); return nullptr; } #endif @@ -153,8 +153,8 @@ Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void mono_time->last_clock_update = false; if (pthread_mutex_init(&mono_time->last_clock_lock, nullptr) < 0) { - free(mono_time->time_update_lock); - free(mono_time); + mem_delete(mem, mono_time->time_update_lock); + mem_delete(mem, mono_time); return nullptr; } @@ -173,7 +173,7 @@ Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void return mono_time; } -void mono_time_free(Mono_Time *mono_time) +void mono_time_free(const Memory *mem, Mono_Time *mono_time) { if (mono_time == nullptr) { return; @@ -183,9 +183,9 @@ void mono_time_free(Mono_Time *mono_time) #endif #ifndef ESP_PLATFORM pthread_rwlock_destroy(mono_time->time_update_lock); - free(mono_time->time_update_lock); + mem_delete(mem, mono_time->time_update_lock); #endif - free(mono_time); + mem_delete(mem, mono_time); } void mono_time_update(Mono_Time *mono_time) diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h index 5a36724715..fa1df840e0 100644 --- a/toxcore/mono_time.h +++ b/toxcore/mono_time.h @@ -9,6 +9,7 @@ #include #include "attributes.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -47,11 +48,11 @@ typedef struct Mono_Time Mono_Time; typedef uint64_t mono_time_current_time_cb(void *user_data); -nullable(1, 2) -Mono_Time *mono_time_new(mono_time_current_time_cb *current_time_callback, void *user_data); +non_null(1) nullable(2, 3) +Mono_Time *mono_time_new(const Memory *mem, mono_time_current_time_cb *current_time_callback, void *user_data); -nullable(1) -void mono_time_free(Mono_Time *mono_time); +non_null(1) nullable(2) +void mono_time_free(const Memory *mem, Mono_Time *mono_time); /** * Update mono_time; subsequent calls to mono_time_get or mono_time_is_timeout diff --git a/toxcore/mono_time_test.cc b/toxcore/mono_time_test.cc index 08ac41f332..379b606c8e 100644 --- a/toxcore/mono_time_test.cc +++ b/toxcore/mono_time_test.cc @@ -6,7 +6,8 @@ namespace { TEST(MonoTime, UnixTimeIncreasesOverTime) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); + const Memory *mem = system_memory(); + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); ASSERT_NE(mono_time, nullptr); mono_time_update(mono_time); @@ -19,12 +20,13 @@ TEST(MonoTime, UnixTimeIncreasesOverTime) uint64_t const end = mono_time_get(mono_time); EXPECT_GT(end, start); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } TEST(MonoTime, IsTimeout) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); + const Memory *mem = system_memory(); + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); ASSERT_NE(mono_time, nullptr); uint64_t const start = mono_time_get(mono_time); @@ -36,12 +38,13 @@ TEST(MonoTime, IsTimeout) EXPECT_TRUE(mono_time_is_timeout(mono_time, start, 1)); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } TEST(MonoTime, CustomTime) { - Mono_Time *mono_time = mono_time_new(nullptr, nullptr); + const Memory *mem = system_memory(); + Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr); ASSERT_NE(mono_time, nullptr); uint64_t test_time = current_time_monotonic(mono_time) + 42137; @@ -61,7 +64,7 @@ TEST(MonoTime, CustomTime) EXPECT_EQ(current_time_monotonic(mono_time), test_time); - mono_time_free(mono_time); + mono_time_free(mem, mono_time); } } // namespace diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 71f6e39e64..7fb4b3a813 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -127,6 +127,7 @@ static const Crypto_Connection empty_crypto_connection = {{0}}; struct Net_Crypto { const Logger *log; + const Memory *mem; const Random *rng; Mono_Time *mono_time; const Network *ns; @@ -758,7 +759,7 @@ static uint32_t num_packets_array(const Packets_Array *array) * @retval 0 on success. */ non_null() -static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packet_Data *data) +static int add_data_to_buffer(const Memory *mem, Packets_Array *array, uint32_t number, const Packet_Data *data) { if (number - array->buffer_start >= CRYPTO_PACKET_BUFFER_SIZE) { return -1; @@ -770,7 +771,7 @@ static int add_data_to_buffer(Packets_Array *array, uint32_t number, const Packe return -1; } - Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data)); + Packet_Data *new_d = (Packet_Data *)mem_alloc(mem, sizeof(Packet_Data)); if (new_d == nullptr) { return -1; @@ -817,7 +818,7 @@ static int get_data_pointer(const Packets_Array *array, Packet_Data **data, uint * @return packet number on success. */ non_null() -static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array, const Packet_Data *data) +static int64_t add_data_end_of_buffer(const Logger *logger, const Memory *mem, Packets_Array *array, const Packet_Data *data) { const uint32_t num_spots = num_packets_array(array); @@ -826,7 +827,7 @@ static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array return -1; } - Packet_Data *new_d = (Packet_Data *)calloc(1, sizeof(Packet_Data)); + Packet_Data *new_d = (Packet_Data *)mem_alloc(mem, sizeof(Packet_Data)); if (new_d == nullptr) { LOGGER_ERROR(logger, "packet data allocation failed"); @@ -846,7 +847,7 @@ static int64_t add_data_end_of_buffer(const Logger *logger, Packets_Array *array * @return packet number on success. */ non_null() -static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data) +static int64_t read_data_beg_buffer(const Memory *mem, Packets_Array *array, Packet_Data *data) { if (array->buffer_end == array->buffer_start) { return -1; @@ -861,7 +862,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data) *data = *array->buffer[num]; const uint32_t id = array->buffer_start; ++array->buffer_start; - free(array->buffer[num]); + mem_delete(mem, array->buffer[num]); array->buffer[num] = nullptr; return id; } @@ -872,7 +873,7 @@ static int64_t read_data_beg_buffer(Packets_Array *array, Packet_Data *data) * @retval 0 on success */ non_null() -static int clear_buffer_until(Packets_Array *array, uint32_t number) +static int clear_buffer_until(const Memory *mem, Packets_Array *array, uint32_t number) { const uint32_t num_spots = num_packets_array(array); @@ -886,7 +887,7 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number) const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; if (array->buffer[num] != nullptr) { - free(array->buffer[num]); + mem_delete(mem, array->buffer[num]); array->buffer[num] = nullptr; } } @@ -896,7 +897,7 @@ static int clear_buffer_until(Packets_Array *array, uint32_t number) } non_null() -static int clear_buffer(Packets_Array *array) +static int clear_buffer(const Memory *mem, Packets_Array *array) { uint32_t i; @@ -904,7 +905,7 @@ static int clear_buffer(Packets_Array *array) const uint32_t num = i % CRYPTO_PACKET_BUFFER_SIZE; if (array->buffer[num] != nullptr) { - free(array->buffer[num]); + mem_delete(mem, array->buffer[num]); array->buffer[num] = nullptr; } } @@ -995,7 +996,7 @@ static int generate_request_packet(uint8_t *data, uint16_t length, const Packets * @return number of requested packets on success. */ non_null() -static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array, +static int handle_request_packet(const Memory *mem, Mono_Time *mono_time, Packets_Array *send_array, const uint8_t *data, uint16_t length, uint64_t *latest_send_time, uint64_t rtt_time) { @@ -1044,7 +1045,7 @@ static int handle_request_packet(Mono_Time *mono_time, Packets_Array *send_array if (send_array->buffer[num] != nullptr) { l_sent_time = max_u64(l_sent_time, send_array->buffer[num]->sent_time); - free(send_array->buffer[num]); + mem_delete(mem, send_array->buffer[num]); send_array->buffer[num] = nullptr; } } @@ -1204,7 +1205,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons dt.length = length; memcpy(dt.data, data, length); pthread_mutex_lock(conn->mutex); - const int64_t packet_num = add_data_end_of_buffer(c->log, &conn->send_array, &dt); + const int64_t packet_num = add_data_end_of_buffer(c->log, c->mem, &conn->send_array, &dt); pthread_mutex_unlock(conn->mutex); if (packet_num == -1) { @@ -1384,14 +1385,14 @@ static int new_temp_packet(const Net_Crypto *c, int crypt_connection_id, const u return -1; } - uint8_t *temp_packet = (uint8_t *)malloc(length); + uint8_t *temp_packet = (uint8_t *)mem_balloc(c->mem, length); if (temp_packet == nullptr) { return -1; } if (conn->temp_packet != nullptr) { - free(conn->temp_packet); + mem_delete(c->mem, conn->temp_packet); } memcpy(temp_packet, packet, length); @@ -1417,7 +1418,7 @@ static int clear_temp_packet(const Net_Crypto *c, int crypt_connection_id) } if (conn->temp_packet != nullptr) { - free(conn->temp_packet); + mem_delete(c->mem, conn->temp_packet); } conn->temp_packet = nullptr; @@ -1575,7 +1576,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const rtt_calc_time = packet_time->sent_time; } - if (clear_buffer_until(&conn->send_array, buffer_start) != 0) { + if (clear_buffer_until(c->mem, &conn->send_array, buffer_start) != 0) { return -1; } } @@ -1616,9 +1617,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const rtt_time = DEFAULT_TCP_PING_CONNECTION; } - const int requested = handle_request_packet(c->mono_time, &conn->send_array, - real_data, real_length, - &rtt_calc_time, rtt_time); + const int requested = handle_request_packet(c->mem, c->mono_time, &conn->send_array, real_data, real_length, &rtt_calc_time, rtt_time); if (requested == -1) { return -1; @@ -1630,13 +1629,13 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const dt.length = real_length; memcpy(dt.data, real_data, real_length); - if (add_data_to_buffer(&conn->recv_array, num, &dt) != 0) { + if (add_data_to_buffer(c->mem, &conn->recv_array, num, &dt) != 0) { return -1; } while (true) { pthread_mutex_lock(conn->mutex); - const int ret = read_data_beg_buffer(&conn->recv_array, &dt); + const int ret = read_data_beg_buffer(c->mem, &conn->recv_array, &dt); pthread_mutex_unlock(conn->mutex); if (ret == -1) { @@ -1804,20 +1803,20 @@ static int handle_packet_connection(Net_Crypto *c, int crypt_connection_id, cons /** @brief Set the size of the friend list to numfriends. * - * @retval -1 if realloc fails. + * @retval -1 if mem_vrealloc fails. * @retval 0 if it succeeds. */ non_null() static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num) { if (num == 0) { - free(c->crypto_connections); + mem_delete(c->mem, c->crypto_connections); c->crypto_connections = nullptr; return 0; } - Crypto_Connection *newcrypto_connections = (Crypto_Connection *)realloc(c->crypto_connections, - num * sizeof(Crypto_Connection)); + Crypto_Connection *newcrypto_connections = (Crypto_Connection *)mem_vrealloc( + c->mem, c->crypto_connections, num, sizeof(Crypto_Connection)); if (newcrypto_connections == nullptr) { return -1; @@ -1870,7 +1869,7 @@ static int create_crypto_connection(Net_Crypto *c) c->crypto_connections[id].last_packets_left_rem = 0; c->crypto_connections[id].packet_send_rate_requested = 0; c->crypto_connections[id].last_packets_left_requested_rem = 0; - c->crypto_connections[id].mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); + c->crypto_connections[id].mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t)); if (c->crypto_connections[id].mutex == nullptr) { pthread_mutex_unlock(&c->connections_mutex); @@ -1878,7 +1877,7 @@ static int create_crypto_connection(Net_Crypto *c) } if (pthread_mutex_init(c->crypto_connections[id].mutex, nullptr) != 0) { - free(c->crypto_connections[id].mutex); + mem_delete(c->mem, c->crypto_connections[id].mutex); pthread_mutex_unlock(&c->connections_mutex); return -1; } @@ -1915,7 +1914,7 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id) uint32_t i; pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex); - free(c->crypto_connections[crypt_connection_id].mutex); + mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex); crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection)); /* check if we can resize the connections array */ @@ -2019,7 +2018,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, void *userdata) { New_Connection n_c; - n_c.cookie = (uint8_t *)malloc(COOKIE_LENGTH); + n_c.cookie = (uint8_t *)mem_balloc(c->mem, COOKIE_LENGTH); if (n_c.cookie == nullptr) { return -1; @@ -2030,7 +2029,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, if (!handle_crypto_handshake(c, n_c.recv_nonce, n_c.peersessionpublic_key, n_c.public_key, n_c.dht_public_key, n_c.cookie, data, length, nullptr)) { - free(n_c.cookie); + mem_delete(c->mem, n_c.cookie); return -1; } @@ -2047,7 +2046,7 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, connection_kill(c, crypt_connection_id, userdata); } else { if (conn->status != CRYPTO_CONN_COOKIE_REQUESTING && conn->status != CRYPTO_CONN_HANDSHAKE_SENT) { - free(n_c.cookie); + mem_delete(c->mem, n_c.cookie); return -1; } @@ -2058,18 +2057,18 @@ static int handle_new_connection_handshake(Net_Crypto *c, const IP_Port *source, crypto_connection_add_source(c, crypt_connection_id, source); if (create_send_handshake(c, crypt_connection_id, n_c.cookie, n_c.dht_public_key) != 0) { - free(n_c.cookie); + mem_delete(c->mem, n_c.cookie); return -1; } conn->status = CRYPTO_CONN_NOT_CONFIRMED; - free(n_c.cookie); + mem_delete(c->mem, n_c.cookie); return 0; } } const int ret = c->new_connection_callback(c->new_connection_callback_object, &n_c); - free(n_c.cookie); + mem_delete(c->mem, n_c.cookie); return ret; } @@ -3045,8 +3044,8 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id) bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id); bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id); clear_temp_packet(c, crypt_connection_id); - clear_buffer(&conn->send_array); - clear_buffer(&conn->recv_array); + clear_buffer(c->mem, &conn->send_array); + clear_buffer(c->mem, &conn->recv_array); ret = wipe_crypto_connection(c, crypt_connection_id); } @@ -3109,27 +3108,29 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk) /** @brief Create new instance of Net_Crypto. * Sets all the global connection variables to their default values. */ -Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info) +Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, + Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info) { if (dht == nullptr) { return nullptr; } - Net_Crypto *temp = (Net_Crypto *)calloc(1, sizeof(Net_Crypto)); + Net_Crypto *temp = (Net_Crypto *)mem_alloc(mem, sizeof(Net_Crypto)); if (temp == nullptr) { return nullptr; } temp->log = log; + temp->mem = mem; temp->rng = rng; temp->mono_time = mono_time; temp->ns = ns; - temp->tcp_c = new_tcp_connections(log, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info); + temp->tcp_c = new_tcp_connections(log, mem, rng, ns, mono_time, dht_get_self_secret_key(dht), proxy_info); if (temp->tcp_c == nullptr) { - free(temp); + mem_delete(mem, temp); return nullptr; } @@ -3139,7 +3140,7 @@ Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network * if (create_recursive_mutex(&temp->tcp_mutex) != 0 || pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) { kill_tcp_connections(temp->tcp_c); - free(temp); + mem_delete(mem, temp); return nullptr; } @@ -3210,6 +3211,8 @@ void kill_net_crypto(Net_Crypto *c) return; } + const Memory *mem = c->mem; + for (uint32_t i = 0; i < c->crypto_connections_length; ++i) { crypto_kill(c, i); } @@ -3224,5 +3227,5 @@ void kill_net_crypto(Net_Crypto *c) networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_HS, nullptr, nullptr); networking_registerhandler(dht_get_net(c->dht), NET_PACKET_CRYPTO_DATA, nullptr, nullptr); crypto_memzero(c, sizeof(Net_Crypto)); - free(c); + mem_delete(mem, c); } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 0c3dfd0d45..ac6a0b59cb 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -398,7 +398,8 @@ void load_secret_key(Net_Crypto *c, const uint8_t *sk); * Sets all the global connection variables to their default values. */ non_null() -Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network *ns, Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info); +Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *rng, const Network *ns, + Mono_Time *mono_time, DHT *dht, const TCP_Proxy_Info *proxy_info); /** return the optimal interval in ms for running do_net_crypto. */ non_null() diff --git a/toxcore/network.c b/toxcore/network.c index 8544496c1c..5ccf068f53 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -898,6 +898,7 @@ typedef struct Packet_Handler { struct Networking_Core { const Logger *log; + const Memory *mem; Packet_Handler packethandlers[256]; const Network *ns; @@ -1009,7 +1010,7 @@ int sendpacket(const Networking_Core *net, const IP_Port *ip_port, const uint8_t * Packet length is put into length. */ non_null() -static int receivepacket(const Network *ns, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) +static int receivepacket(const Network *ns, const Memory *mem, const Logger *log, Socket sock, IP_Port *ip_port, uint8_t *data, uint32_t *length) { memset(ip_port, 0, sizeof(IP_Port)); Network_Addr addr = {{0}}; @@ -1088,7 +1089,7 @@ void networking_poll(const Networking_Core *net, void *userdata) uint8_t data[MAX_UDP_PACKET_SIZE]; uint32_t length; - while (receivepacket(net->ns, net->log, net->sock, &ip_port, data, &length) != -1) { + while (receivepacket(net->ns, net->mem, net->log, net->sock, &ip_port, data, &length) != -1) { if (length < 1) { continue; } @@ -1117,7 +1118,7 @@ void networking_poll(const Networking_Core *net, void *userdata) * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other. */ Networking_Core *new_networking_ex( - const Logger *log, const Network *ns, const IP *ip, + const Logger *log, const Memory *mem, const Network *ns, const IP *ip, uint16_t port_from, uint16_t port_to, unsigned int *error) { /* If both from and to are 0, use default port range @@ -1147,7 +1148,7 @@ Networking_Core *new_networking_ex( return nullptr; } - Networking_Core *temp = (Networking_Core *)calloc(1, sizeof(Networking_Core)); + Networking_Core *temp = (Networking_Core *)mem_alloc(mem, sizeof(Networking_Core)); if (temp == nullptr) { return nullptr; @@ -1155,6 +1156,7 @@ Networking_Core *new_networking_ex( temp->ns = ns; temp->log = log; + temp->mem = mem; temp->family = ip->family; temp->port = 0; @@ -1168,7 +1170,7 @@ Networking_Core *new_networking_ex( char *strerror = net_new_strerror(neterror); LOGGER_ERROR(log, "failed to get a socket?! %d, %s", neterror, strerror); net_kill_strerror(strerror); - free(temp); + mem_delete(mem, temp); if (error != nullptr) { *error = 1; @@ -1246,7 +1248,7 @@ Networking_Core *new_networking_ex( portptr = &addr6->sin6_port; } else { - free(temp); + mem_delete(mem, temp); return nullptr; } @@ -1350,10 +1352,10 @@ Networking_Core *new_networking_ex( return nullptr; } -Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns) +Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, const Network *ns) { /* this is the easiest way to completely disable UDP without changing too much code. */ - Networking_Core *net = (Networking_Core *)calloc(1, sizeof(Networking_Core)); + Networking_Core *net = (Networking_Core *)mem_alloc(mem, sizeof(Networking_Core)); if (net == nullptr) { return nullptr; @@ -1361,6 +1363,7 @@ Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns) net->ns = ns; net->log = log; + net->mem = mem; return net; } @@ -1377,7 +1380,7 @@ void kill_networking(Networking_Core *net) kill_sock(net->ns, net->sock); } - free(net); + mem_delete(net->mem, net); } @@ -1712,7 +1715,7 @@ bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP return true; } -bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port) +bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port) { struct sockaddr_storage addr = {0}; size_t addrsize; @@ -1765,13 +1768,13 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port) return true; } -int32_t net_getipport(const char *node, IP_Port **res, int tox_type) +int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type) { // Try parsing as IP address first. IP_Port parsed = {{{0}}}; if (addr_parse_ip(node, &parsed.ip)) { - IP_Port *tmp = (IP_Port *)calloc(1, sizeof(IP_Port)); + IP_Port *tmp = (IP_Port *)mem_alloc(mem, sizeof(IP_Port)); if (tmp == nullptr) { return -1; @@ -1784,7 +1787,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if ((true)) { - *res = (IP_Port *)calloc(1, sizeof(IP_Port)); + *res = (IP_Port *)mem_alloc(mem, sizeof(IP_Port)); assert(*res != nullptr); IP_Port *ip_port = *res; ip_port->ip.ip.v4.uint32 = net_htonl(0x7F000003); // 127.0.0.3 @@ -1827,7 +1830,7 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) return 0; } - *res = (IP_Port *)calloc(count, sizeof(IP_Port)); + *res = (IP_Port *)mem_valloc(mem, count, sizeof(IP_Port)); if (*res == nullptr) { freeaddrinfo(infos); @@ -1869,9 +1872,9 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) return count; } -void net_freeipport(IP_Port *ip_ports) +void net_freeipport(const Memory *mem, IP_Port *ip_ports) { - free(ip_ports); + mem_delete(mem, ip_ports); } bool bind_to_port(const Network *ns, Socket sock, Family family, uint16_t port) diff --git a/toxcore/network.h b/toxcore/network.h index ffc04ed6e4..2f518c1d91 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -14,6 +14,7 @@ #include // uint*_t #include "logger.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -533,7 +534,7 @@ void networking_poll(const Networking_Core *net, void *userdata); * Return false on failure. */ non_null() -bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port); +bool net_connect(const Memory *mem, const Logger *log, Socket sock, const IP_Port *ip_port); /** @brief High-level getaddrinfo implementation. * @@ -549,11 +550,11 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port); * @retval -1 on error. */ non_null() -int32_t net_getipport(const char *node, IP_Port **res, int tox_type); +int32_t net_getipport(const Memory *mem, const char *node, IP_Port **res, int tox_type); /** Deallocates memory allocated by net_getipport */ -nullable(1) -void net_freeipport(IP_Port *ip_ports); +non_null(1) nullable(2) +void net_freeipport(const Memory *mem, IP_Port *ip_ports); /** * @return true on success, false on failure. @@ -600,13 +601,13 @@ void net_kill_strerror(char *strerror); * * If error is non NULL it is set to 0 if no issues, 1 if socket related error, 2 if other. */ -non_null(1, 2, 3) nullable(6) +non_null(1, 2, 3, 4) nullable(7) Networking_Core *new_networking_ex( - const Logger *log, const Network *ns, const IP *ip, + const Logger *log, const Memory *mem, const Network *ns, const IP *ip, uint16_t port_from, uint16_t port_to, unsigned int *error); non_null() -Networking_Core *new_networking_no_udp(const Logger *log, const Network *ns); +Networking_Core *new_networking_no_udp(const Logger *log, const Memory *mem, const Network *ns); /** Function to cleanup networking stuff (doesn't do much right now). */ nullable(1) diff --git a/toxcore/onion.c b/toxcore/onion.c index 63ff6d8520..d7ec8bfd78 100644 --- a/toxcore/onion.c +++ b/toxcore/onion.c @@ -668,13 +668,13 @@ void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *o onion->callback_object = object; } -Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht) +Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht) { if (dht == nullptr) { return nullptr; } - Onion *onion = (Onion *)calloc(1, sizeof(Onion)); + Onion *onion = (Onion *)mem_alloc(mem, sizeof(Onion)); if (onion == nullptr) { return nullptr; @@ -685,13 +685,14 @@ Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rn onion->net = dht_get_net(dht); onion->mono_time = mono_time; onion->rng = rng; + onion->mem = mem; new_symmetric_key(rng, onion->secret_symmetric_key); onion->timestamp = mono_time_get(onion->mono_time); const uint8_t *secret_key = dht_get_self_secret_key(dht); - onion->shared_keys_1 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); - onion->shared_keys_2 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); - onion->shared_keys_3 = shared_key_cache_new(mono_time, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion->shared_keys_1 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion->shared_keys_2 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion->shared_keys_3 = shared_key_cache_new(mono_time, mem, secret_key, KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (onion->shared_keys_1 == nullptr || onion->shared_keys_2 == nullptr || @@ -732,5 +733,5 @@ void kill_onion(Onion *onion) shared_key_cache_free(onion->shared_keys_2); shared_key_cache_free(onion->shared_keys_3); - free(onion); + mem_delete(onion->mem, onion); } diff --git a/toxcore/onion.h b/toxcore/onion.h index 5c8f920b44..7f71c2493d 100644 --- a/toxcore/onion.h +++ b/toxcore/onion.h @@ -20,6 +20,7 @@ typedef struct Onion { const Logger *log; const Mono_Time *mono_time; const Random *rng; + const Memory *mem; DHT *dht; Networking_Core *net; uint8_t secret_symmetric_key[CRYPTO_SYMMETRIC_KEY_SIZE]; @@ -147,7 +148,7 @@ non_null(1) nullable(2, 3) void set_callback_handle_recv_1(Onion *onion, onion_recv_1_cb *function, void *object); non_null() -Onion *new_onion(const Logger *log, const Mono_Time *mono_time, const Random *rng, DHT *dht); +Onion *new_onion(const Logger *log, const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht); nullable(1) void kill_onion(Onion *onion); diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c index fb04d21f56..551e7b1fae 100644 --- a/toxcore/onion_announce.c +++ b/toxcore/onion_announce.c @@ -51,6 +51,7 @@ struct Onion_Announce { const Logger *log; const Mono_Time *mono_time; const Random *rng; + const Memory *mem; DHT *dht; Networking_Core *net; Onion_Announce_Entry entries[ONION_ANNOUNCE_MAX_ENTRIES]; @@ -316,12 +317,13 @@ static int cmp_entry(const void *a, const void *b) } non_null() -static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int length, const Mono_Time *mono_time, +static void sort_onion_announce_list(const Memory *mem, const Mono_Time *mono_time, + Onion_Announce_Entry *list, unsigned int length, const uint8_t *comp_public_key) { // Pass comp_public_key to qsort with each Client_data entry, so the // comparison function can use it as the base of comparison. - Cmp_Data *cmp_list = (Cmp_Data *)calloc(length, sizeof(Cmp_Data)); + Cmp_Data *cmp_list = (Cmp_Data *)mem_valloc(mem, length, sizeof(Cmp_Data)); if (cmp_list == nullptr) { return; @@ -339,7 +341,7 @@ static void sort_onion_announce_list(Onion_Announce_Entry *list, unsigned int le list[i] = cmp_list[i].entry; } - free(cmp_list); + mem_delete(mem, cmp_list); } /** @brief add entry to entries list @@ -377,7 +379,8 @@ static int add_to_entries(Onion_Announce *onion_a, const IP_Port *ret_ip_port, c memcpy(onion_a->entries[pos].data_public_key, data_public_key, CRYPTO_PUBLIC_KEY_SIZE); onion_a->entries[pos].announce_time = mono_time_get(onion_a->mono_time); - sort_onion_announce_list(onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, onion_a->mono_time, + sort_onion_announce_list(onion_a->mem, onion_a->mono_time, + onion_a->entries, ONION_ANNOUNCE_MAX_ENTRIES, dht_get_self_public_key(onion_a->dht)); return in_entries(onion_a, public_key); } @@ -438,7 +441,7 @@ static int handle_announce_request_common( return 1; } - uint8_t *plain = (uint8_t *)malloc(plain_size); + uint8_t *plain = (uint8_t *)mem_balloc(onion_a->mem, plain_size); if (plain == nullptr) { return 1; @@ -448,7 +451,7 @@ static int handle_announce_request_common( packet + 1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE, plain_size + CRYPTO_MAC_SIZE, plain); if ((uint32_t)decrypted_len != plain_size) { - free(plain); + mem_delete(onion_a->mem, plain); return 1; } @@ -483,10 +486,10 @@ static int handle_announce_request_common( const uint16_t response_size = nodes_offset + MAX_SENT_NODES * PACKED_NODE_SIZE_IP6 + max_extra_size; - uint8_t *response = (uint8_t *)malloc(response_size); + uint8_t *response = (uint8_t *)mem_balloc(onion_a->mem, response_size); if (response == nullptr) { - free(plain); + mem_delete(onion_a->mem, plain); return 1; } @@ -504,8 +507,8 @@ static int handle_announce_request_common( if (nodes_length <= 0) { LOGGER_WARNING(onion_a->log, "Failed to pack nodes"); - free(response); - free(plain); + mem_delete(onion_a->mem, response); + mem_delete(onion_a->mem, plain); return 1; } } @@ -523,8 +526,8 @@ static int handle_announce_request_common( response, response_size, offset); if (extra_size == -1) { - free(response); - free(plain); + mem_delete(onion_a->mem, response); + mem_delete(onion_a->mem, plain); return 1; } @@ -536,8 +539,8 @@ static int handle_announce_request_common( if (len != offset + CRYPTO_MAC_SIZE) { LOGGER_ERROR(onion_a->log, "Failed to encrypt announce response"); - free(response); - free(plain); + mem_delete(onion_a->mem, response); + mem_delete(onion_a->mem, plain); return 1; } @@ -549,13 +552,13 @@ static int handle_announce_request_common( if (send_onion_response(onion_a->net, source, data, 1 + ONION_ANNOUNCE_SENDBACK_DATA_LENGTH + CRYPTO_NONCE_SIZE + len, packet + (length - ONION_RETURN_3)) == -1) { - free(response); - free(plain); + mem_delete(onion_a->mem, response); + mem_delete(onion_a->mem, plain); return 1; } - free(response); - free(plain); + mem_delete(onion_a->mem, response); + mem_delete(onion_a->mem, plain); return 0; } @@ -639,13 +642,13 @@ static int handle_data_request(void *object, const IP_Port *source, const uint8_ return 0; } -Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht) +Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht) { if (dht == nullptr) { return nullptr; } - Onion_Announce *onion_a = (Onion_Announce *)calloc(1, sizeof(Onion_Announce)); + Onion_Announce *onion_a = (Onion_Announce *)mem_alloc(mem, sizeof(Onion_Announce)); if (onion_a == nullptr) { return nullptr; @@ -653,6 +656,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const M onion_a->log = log; onion_a->rng = rng; + onion_a->mem = mem; onion_a->mono_time = mono_time; onion_a->dht = dht; onion_a->net = dht_get_net(dht); @@ -661,7 +665,7 @@ Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const M onion_a->extra_data_object = nullptr; new_hmac_key(rng, onion_a->hmac_key); - onion_a->shared_keys_recv = shared_key_cache_new(mono_time, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); + onion_a->shared_keys_recv = shared_key_cache_new(mono_time, mem, dht_get_self_secret_key(dht), KEYS_TIMEOUT, MAX_KEYS_PER_SLOT); if (onion_a->shared_keys_recv == nullptr) { kill_onion_announce(onion_a); return nullptr; @@ -687,5 +691,5 @@ void kill_onion_announce(Onion_Announce *onion_a) crypto_memzero(onion_a->hmac_key, CRYPTO_HMAC_KEY_SIZE); shared_key_cache_free(onion_a->shared_keys_recv); - free(onion_a); + mem_delete(onion_a->mem, onion_a); } diff --git a/toxcore/onion_announce.h b/toxcore/onion_announce.h index 24303abccb..857f4706ac 100644 --- a/toxcore/onion_announce.h +++ b/toxcore/onion_announce.h @@ -131,7 +131,7 @@ void onion_announce_extra_data_callback(Onion_Announce *onion_a, uint16_t extra_ pack_extra_data_cb *extra_data_callback, void *extra_data_object); non_null() -Onion_Announce *new_onion_announce(const Logger *log, const Random *rng, const Mono_Time *mono_time, DHT *dht); +Onion_Announce *new_onion_announce(const Logger *log, const Memory *mem, const Random *rng, const Mono_Time *mono_time, DHT *dht); nullable(1) void kill_onion_announce(Onion_Announce *onion_a); diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index ff63473e10..6aef15ec3a 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -106,6 +106,7 @@ struct Onion_Client { const Mono_Time *mono_time; const Logger *logger; const Random *rng; + const Memory *mem; DHT *dht; Net_Crypto *c; @@ -731,12 +732,12 @@ static int onion_client_cmp_entry(const void *a, const void *b) } non_null() -static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mono_Time *mono_time, - const uint8_t *comp_public_key) +static void sort_onion_node_list(const Memory *mem, const Mono_Time *mono_time, + Onion_Node *list, unsigned int length, const uint8_t *comp_public_key) { // Pass comp_public_key to qsort with each Client_data entry, so the // comparison function can use it as the base of comparison. - Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)calloc(length, sizeof(Onion_Client_Cmp_Data)); + Onion_Client_Cmp_Data *cmp_list = (Onion_Client_Cmp_Data *)mem_valloc(mem, length, sizeof(Onion_Client_Cmp_Data)); if (cmp_list == nullptr) { return; @@ -754,7 +755,7 @@ static void sort_onion_node_list(Onion_Node *list, unsigned int length, const Mo list[i] = cmp_list[i].entry; } - free(cmp_list); + mem_delete(mem, cmp_list); } non_null() @@ -787,7 +788,7 @@ static int client_add_to_list(Onion_Client *onion_c, uint32_t num, const uint8_t list_length = MAX_ONION_CLIENTS; } - sort_onion_node_list(node_list, list_length, onion_c->mono_time, reference_id); + sort_onion_node_list(onion_c->mem, onion_c->mono_time, node_list, list_length, reference_id); int index = -1; bool stored = false; @@ -1457,19 +1458,19 @@ int onion_friend_num(const Onion_Client *onion_c, const uint8_t *public_key) /** @brief Set the size of the friend list to num. * - * @retval -1 if realloc fails. + * @retval -1 if mem_vrealloc fails. * @retval 0 if it succeeds. */ non_null() static int realloc_onion_friends(Onion_Client *onion_c, uint32_t num) { if (num == 0) { - free(onion_c->friends_list); + mem_delete(onion_c->mem, onion_c->friends_list); onion_c->friends_list = nullptr; return 0; } - Onion_Friend *newonion_friends = (Onion_Friend *)realloc(onion_c->friends_list, num * sizeof(Onion_Friend)); + Onion_Friend *newonion_friends = (Onion_Friend *)mem_vrealloc(onion_c->mem, onion_c->friends_list, num, sizeof(Onion_Friend)); if (newonion_friends == nullptr) { return -1; @@ -2074,28 +2075,29 @@ void do_onion_client(Onion_Client *onion_c) onion_c->last_run = mono_time_get(onion_c->mono_time); } -Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c) +Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c) { if (c == nullptr) { return nullptr; } - Onion_Client *onion_c = (Onion_Client *)calloc(1, sizeof(Onion_Client)); + Onion_Client *onion_c = (Onion_Client *)mem_alloc(mem, sizeof(Onion_Client)); if (onion_c == nullptr) { return nullptr; } - onion_c->announce_ping_array = ping_array_new(ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT); + onion_c->announce_ping_array = ping_array_new(mem, ANNOUNCE_ARRAY_SIZE, ANNOUNCE_TIMEOUT); if (onion_c->announce_ping_array == nullptr) { - free(onion_c); + mem_delete(mem, onion_c); return nullptr; } onion_c->mono_time = mono_time; onion_c->logger = logger; onion_c->rng = rng; + onion_c->mem = mem; onion_c->dht = nc_get_dht(c); onion_c->net = dht_get_net(onion_c->dht); onion_c->c = c; @@ -2117,6 +2119,8 @@ void kill_onion_client(Onion_Client *onion_c) return; } + const Memory *mem = onion_c->mem; + ping_array_kill(onion_c->announce_ping_array); realloc_onion_friends(onion_c, 0); networking_registerhandler(onion_c->net, NET_PACKET_ANNOUNCE_RESPONSE, nullptr, nullptr); @@ -2126,5 +2130,5 @@ void kill_onion_client(Onion_Client *onion_c) cryptopacket_registerhandler(onion_c->dht, CRYPTO_PACKET_DHTPK, nullptr, nullptr); set_onion_packet_tcp_connection_callback(nc_get_tcp_c(onion_c->c), nullptr, nullptr); crypto_memzero(onion_c, sizeof(Onion_Client)); - free(onion_c); + mem_delete(mem, onion_c); } diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 23a48ef5e6..6498f8c5c3 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h @@ -208,7 +208,7 @@ non_null() void do_onion_client(Onion_Client *onion_c); non_null() -Onion_Client *new_onion_client(const Logger *logger, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c); +Onion_Client *new_onion_client(const Logger *logger, const Memory *mem, const Random *rng, const Mono_Time *mono_time, Net_Crypto *c); nullable(1) void kill_onion_client(Onion_Client *onion_c); diff --git a/toxcore/ping.c b/toxcore/ping.c index f44777b8ee..f8a96edfb9 100644 --- a/toxcore/ping.c +++ b/toxcore/ping.c @@ -336,18 +336,18 @@ void ping_iterate(Ping *ping) } -Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht) +Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht) { - Ping *ping = (Ping *)calloc(1, sizeof(Ping)); + Ping *ping = (Ping *)mem_alloc(mem, sizeof(Ping)); if (ping == nullptr) { return nullptr; } - ping->ping_array = ping_array_new(PING_NUM_MAX, PING_TIMEOUT); + ping->ping_array = ping_array_new(mem, PING_NUM_MAX, PING_TIMEOUT); if (ping->ping_array == nullptr) { - free(ping); + mem_delete(mem, ping); return nullptr; } @@ -360,7 +360,7 @@ Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht) return ping; } -void ping_kill(Ping *ping) +void ping_kill(const Memory *mem, Ping *ping) { if (ping == nullptr) { return; @@ -370,5 +370,5 @@ void ping_kill(Ping *ping) networking_registerhandler(dht_get_net(ping->dht), NET_PACKET_PING_RESPONSE, nullptr, nullptr); ping_array_kill(ping->ping_array); - free(ping); + mem_delete(mem, ping); } diff --git a/toxcore/ping.h b/toxcore/ping.h index da8d7f003e..c561345991 100644 --- a/toxcore/ping.h +++ b/toxcore/ping.h @@ -18,10 +18,10 @@ typedef struct Ping Ping; non_null() -Ping *ping_new(const Mono_Time *mono_time, const Random *rng, DHT *dht); +Ping *ping_new(const Memory *mem, const Mono_Time *mono_time, const Random *rng, DHT *dht); -nullable(1) -void ping_kill(Ping *ping); +non_null(1) nullable(2) +void ping_kill(const Memory *mem, Ping *ping); /** @brief Add nodes to the to_ping list. * All nodes in this list are pinged every TIME_TO_PING seconds diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c index e22a2e6c1c..f303d80215 100644 --- a/toxcore/ping_array.c +++ b/toxcore/ping_array.c @@ -24,6 +24,7 @@ typedef struct Ping_Array_Entry { } Ping_Array_Entry; struct Ping_Array { + const Memory *mem; Ping_Array_Entry *entries; uint32_t last_deleted; /* number representing the next entry to be deleted. */ @@ -32,7 +33,7 @@ struct Ping_Array { uint32_t timeout; /* The timeout after which entries are cleared. */ }; -Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) +Ping_Array *ping_array_new(const Memory *mem, uint32_t size, uint32_t timeout) { if (size == 0 || timeout == 0) { return nullptr; @@ -43,16 +44,17 @@ Ping_Array *ping_array_new(uint32_t size, uint32_t timeout) return nullptr; } - Ping_Array *const empty_array = (Ping_Array *)calloc(1, sizeof(Ping_Array)); + Ping_Array *const empty_array = (Ping_Array *)mem_alloc(mem, sizeof(Ping_Array)); if (empty_array == nullptr) { return nullptr; } - empty_array->entries = (Ping_Array_Entry *)calloc(size, sizeof(Ping_Array_Entry)); + empty_array->mem = mem; + empty_array->entries = (Ping_Array_Entry *)mem_valloc(mem, size, sizeof(Ping_Array_Entry)); if (empty_array->entries == nullptr) { - free(empty_array); + mem_delete(mem, empty_array); return nullptr; } @@ -67,7 +69,7 @@ non_null() static void clear_entry(Ping_Array *array, uint32_t index) { const Ping_Array_Entry empty = {nullptr}; - free(array->entries[index].data); + mem_delete(array->mem, array->entries[index].data); array->entries[index] = empty; } @@ -83,8 +85,8 @@ void ping_array_kill(Ping_Array *array) ++array->last_deleted; } - free(array->entries); - free(array); + mem_delete(array->mem, array->entries); + mem_delete(array->mem, array); } /** Clear timed out entries. */ @@ -114,7 +116,7 @@ uint64_t ping_array_add(Ping_Array *array, const Mono_Time *mono_time, const Ran clear_entry(array, index); } - array->entries[index].data = (uint8_t *)malloc(length); + array->entries[index].data = (uint8_t *)mem_balloc(array->mem, length); if (array->entries[index].data == nullptr) { return 0; diff --git a/toxcore/ping_array.h b/toxcore/ping_array.h index fda84cb110..5fc0401735 100644 --- a/toxcore/ping_array.h +++ b/toxcore/ping_array.h @@ -13,6 +13,7 @@ #include #include "crypto_core.h" +#include "mem.h" #include "mono_time.h" #ifdef __cplusplus @@ -29,7 +30,8 @@ typedef struct Ping_Array Ping_Array; * * @return pointer to allocated Ping_Array on success, nullptr on failure. */ -struct Ping_Array *ping_array_new(uint32_t size, uint32_t timeout); +non_null() +struct Ping_Array *ping_array_new(const Memory *mem, uint32_t size, uint32_t timeout); /** * @brief Free all the allocated memory in a @ref Ping_Array. diff --git a/toxcore/ping_array_test.cc b/toxcore/ping_array_test.cc index 3644103138..8ce557092e 100644 --- a/toxcore/ping_array_test.cc +++ b/toxcore/ping_array_test.cc @@ -15,41 +15,54 @@ struct Ping_Array_Deleter { using Ping_Array_Ptr = std::unique_ptr; struct Mono_Time_Deleter { - void operator()(Mono_Time *arr) { mono_time_free(arr); } + Mono_Time_Deleter(const Memory *mem) + : mem_(mem) + { + } + void operator()(Mono_Time *arr) { mono_time_free(mem_, arr); } + +private: + const Memory *mem_; }; using Mono_Time_Ptr = std::unique_ptr; TEST(PingArray, MinimumTimeoutIsOne) { - EXPECT_EQ(ping_array_new(1, 0), nullptr); - EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr); + const Memory *mem = system_memory(); + EXPECT_EQ(ping_array_new(mem, 1, 0), nullptr); + EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr); } TEST(PingArray, MinimumArraySizeIsOne) { - EXPECT_EQ(ping_array_new(0, 1), nullptr); - EXPECT_NE(Ping_Array_Ptr(ping_array_new(1, 1)), nullptr); + const Memory *mem = system_memory(); + EXPECT_EQ(ping_array_new(mem, 0, 1), nullptr); + EXPECT_NE(Ping_Array_Ptr(ping_array_new(mem, 1, 1)), nullptr); } TEST(PingArray, ArraySizeMustBePowerOfTwo) { + const Memory *mem = system_memory(); + Ping_Array_Ptr arr; - arr.reset(ping_array_new(2, 1)); + arr.reset(ping_array_new(mem, 2, 1)); EXPECT_NE(arr, nullptr); - arr.reset(ping_array_new(4, 1)); + arr.reset(ping_array_new(mem, 4, 1)); EXPECT_NE(arr, nullptr); - arr.reset(ping_array_new(1024, 1)); + arr.reset(ping_array_new(mem, 1024, 1)); EXPECT_NE(arr, nullptr); - EXPECT_EQ(ping_array_new(1023, 1), nullptr); - EXPECT_EQ(ping_array_new(1234, 1), nullptr); + EXPECT_EQ(ping_array_new(mem, 1023, 1), nullptr); + EXPECT_EQ(ping_array_new(mem, 1234, 1), nullptr); } TEST(PingArray, StoredDataCanBeRetrieved) { - Ping_Array_Ptr const arr(ping_array_new(2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr)); + const Memory *mem = system_memory(); + + Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); const Random *rng = system_random(); ASSERT_NE(rng, nullptr); @@ -65,8 +78,10 @@ TEST(PingArray, StoredDataCanBeRetrieved) TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) { - Ping_Array_Ptr const arr(ping_array_new(2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr)); + const Memory *mem = system_memory(); + + Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); const Random *rng = system_random(); ASSERT_NE(rng, nullptr); @@ -86,8 +101,10 @@ TEST(PingArray, RetrievingDataWithTooSmallOutputBufferHasNoEffect) TEST(PingArray, ZeroLengthDataCanBeAdded) { - Ping_Array_Ptr const arr(ping_array_new(2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr)); + const Memory *mem = system_memory(); + + Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); const Random *rng = system_random(); ASSERT_NE(rng, nullptr); @@ -101,8 +118,10 @@ TEST(PingArray, ZeroLengthDataCanBeAdded) TEST(PingArray, PingId0IsInvalid) { - Ping_Array_Ptr const arr(ping_array_new(2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr)); + const Memory *mem = system_memory(); + + Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); uint8_t c = 0; @@ -112,8 +131,10 @@ TEST(PingArray, PingId0IsInvalid) // Protection against replay attacks. TEST(PingArray, DataCanOnlyBeRetrievedOnce) { - Ping_Array_Ptr const arr(ping_array_new(2, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr)); + const Memory *mem = system_memory(); + + Ping_Array_Ptr const arr(ping_array_new(mem, 2, 1)); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); const Random *rng = system_random(); ASSERT_NE(rng, nullptr); @@ -128,8 +149,10 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce) TEST(PingArray, PingIdMustMatchOnCheck) { - Ping_Array_Ptr const arr(ping_array_new(1, 1)); - Mono_Time_Ptr const mono_time(mono_time_new(nullptr, nullptr)); + const Memory *mem = system_memory(); + + Ping_Array_Ptr const arr(ping_array_new(mem, 1, 1)); + Mono_Time_Ptr const mono_time(mono_time_new(mem, nullptr, nullptr), mem); ASSERT_NE(mono_time, nullptr); const Random *rng = system_random(); ASSERT_NE(rng, nullptr); diff --git a/toxcore/shared_key_cache.c b/toxcore/shared_key_cache.c index 7846ae4f69..4b87945ccb 100644 --- a/toxcore/shared_key_cache.c +++ b/toxcore/shared_key_cache.c @@ -6,7 +6,6 @@ #include #include -#include // calloc(...) #include // memcpy(...) #include "ccompat.h" @@ -23,7 +22,8 @@ struct Shared_Key_Cache { Shared_Key *keys; const uint8_t* self_secret_key; uint64_t timeout; /** After this time (in seconds), a key is erased on the next housekeeping cycle */ - const Mono_Time *time; + const Mono_Time *mono_time; + const Memory *mem; uint8_t keys_per_slot; }; @@ -43,37 +43,38 @@ static void shared_key_set_empty(Shared_Key *k) { assert(shared_key_is_empty(k)); } -Shared_Key_Cache *shared_key_cache_new(const Mono_Time *time, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot) +Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot) { - if (time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) { + if (mono_time == nullptr || self_secret_key == nullptr || timeout == 0 || keys_per_slot == 0) { return nullptr; } // Time must not be zero, since we use that as special value for empty slots - if (mono_time_get(time) == 0) { + if (mono_time_get(mono_time) == 0) { // Fail loudly in debug environments assert(false); return nullptr; } - Shared_Key_Cache *res = (Shared_Key_Cache *)calloc(1, sizeof (Shared_Key_Cache)); + Shared_Key_Cache *res = (Shared_Key_Cache *)mem_alloc(mem, sizeof(Shared_Key_Cache)); if (res == nullptr) { return nullptr; } res->self_secret_key = self_secret_key; - res->time = time; + res->mono_time = mono_time; + res->mem = mem; res->keys_per_slot = keys_per_slot; // We take one byte from the public key for each bucket and store keys_per_slot elements there const size_t cache_size = 256 * keys_per_slot; - res->keys = (Shared_Key *)calloc(cache_size, sizeof (Shared_Key)); + res->keys = (Shared_Key *)mem_valloc(mem, cache_size, sizeof(Shared_Key)); if (res->keys == nullptr) { - free(res); + mem_delete(mem, res); return nullptr; } - crypto_memlock(res->keys, cache_size * sizeof (Shared_Key)); + crypto_memlock(res->keys, cache_size * sizeof(Shared_Key)); return res; } @@ -88,15 +89,15 @@ void shared_key_cache_free(Shared_Key_Cache *cache) // Don't leave key material in memory crypto_memzero(cache->keys, cache_size * sizeof (Shared_Key)); crypto_memunlock(cache->keys, cache_size * sizeof (Shared_Key)); - free(cache->keys); - free(cache); + mem_delete(cache->mem, cache->keys); + mem_delete(cache->mem, cache); } /* NOTE: On each lookup housekeeping is performed to evict keys that did timeout. */ const uint8_t *shared_key_cache_lookup(Shared_Key_Cache *cache, const uint8_t public_key[CRYPTO_PUBLIC_KEY_SIZE]) { // caching the time is not necessary, but calls to mono_time_get(...) are not free - const uint64_t cur_time = mono_time_get(cache->time); + const uint64_t cur_time = mono_time_get(cache->mono_time); // We can't use the first and last bytes because they are masked in curve25519. Selected 8 for good alignment. const uint8_t bucket_idx = public_key[8]; Shared_Key* bucket_start = &cache->keys[bucket_idx*cache->keys_per_slot]; diff --git a/toxcore/shared_key_cache.h b/toxcore/shared_key_cache.h index 97d8b7a4a8..dc42b38058 100644 --- a/toxcore/shared_key_cache.h +++ b/toxcore/shared_key_cache.h @@ -8,6 +8,7 @@ #include // uint*_t #include "crypto_core.h" +#include "mem.h" #include "mono_time.h" /** @@ -18,7 +19,7 @@ typedef struct Shared_Key_Cache Shared_Key_Cache; /** * @brief Initializes a new shared key cache. - * @param time Time object for retrieving current time. + * @param mono_time Time object for retrieving current time. * @param self_secret_key Our own secret key of length CRYPTO_SECRET_KEY_SIZE, * it must not change during the lifetime of the cache. * @param timeout Number of milliseconds, after which a key should be evicted. @@ -26,7 +27,7 @@ typedef struct Shared_Key_Cache Shared_Key_Cache; * @return nullptr on error. */ non_null() -Shared_Key_Cache *shared_key_cache_new(const Mono_Time *time, +Shared_Key_Cache *shared_key_cache_new(const Mono_Time *mono_time, const Memory *mem, const uint8_t *self_secret_key, uint64_t timeout, uint8_t keys_per_slot); diff --git a/toxcore/tox.c b/toxcore/tox.c index 3f7dcc439d..d17e61b70f 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -22,6 +22,7 @@ #include "group_chats.h" #include "group_moderation.h" #include "logger.h" +#include "mem.h" #include "mono_time.h" #include "network.h" #include "tox_private.h" @@ -626,18 +627,6 @@ static int tox_load(Tox *tox, const uint8_t *data, uint32_t length) Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) { - Tox *tox = (Tox *)calloc(1, sizeof(Tox)); - - if (tox == nullptr) { - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); - return nullptr; - } - - Messenger_Options m_options = {0}; - - bool load_savedata_sk = false; - bool load_savedata_tox = false; - struct Tox_Options *default_options = nullptr; if (options == nullptr) { @@ -651,7 +640,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) case TOX_ERR_OPTIONS_NEW_MALLOC: { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); - free(tox); return nullptr; } } @@ -660,11 +648,28 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) const struct Tox_Options *const opts = options != nullptr ? options : default_options; assert(opts != nullptr); + const Tox_System *sys = tox_options_get_operating_system(opts); + const Tox_System default_system = tox_default_system(); + + if (sys == nullptr) { + sys = &default_system; + } + + if (sys->rng == nullptr || sys->ns == nullptr || sys->mem == nullptr) { + // TODO(iphydf): Not quite right, but similar. + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); + return nullptr; + } + + Messenger_Options m_options = {0}; + + bool load_savedata_sk = false; + bool load_savedata_tox = false; + if (tox_options_get_savedata_type(opts) != TOX_SAVEDATA_TYPE_NONE) { if (tox_options_get_savedata_data(opts) == nullptr || tox_options_get_savedata_length(opts) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); tox_options_free(default_options); - free(tox); return nullptr; } } @@ -673,7 +678,6 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) if (tox_options_get_savedata_length(opts) != TOX_SECRET_KEY_SIZE) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); tox_options_free(default_options); - free(tox); return nullptr; } @@ -682,14 +686,12 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) if (tox_options_get_savedata_length(opts) < TOX_ENC_SAVE_MAGIC_LENGTH) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_BAD_FORMAT); tox_options_free(default_options); - free(tox); return nullptr; } if (memcmp(tox_options_get_savedata_data(opts), TOX_ENC_SAVE_MAGIC_NUMBER, TOX_ENC_SAVE_MAGIC_LENGTH) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_LOAD_ENCRYPTED); tox_options_free(default_options); - free(tox); return nullptr; } @@ -709,6 +711,13 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) m_options.local_discovery_enabled = false; } + Tox *tox = (Tox *)mem_alloc(sys->mem, sizeof(Tox)); + + if (tox == nullptr) { + SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); + return nullptr; + } + tox->log_callback = tox_options_get_log_callback(opts); m_options.log_callback = tox_log_handler; m_options.log_context = tox; @@ -733,34 +742,18 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) default: { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_TYPE); tox_options_free(default_options); - free(tox); + mem_delete(sys->mem, tox); return nullptr; } } - const Tox_System *sys = tox_options_get_operating_system(opts); - const Tox_System default_system = tox_default_system(); - - if (sys == nullptr) { - sys = &default_system; - } - - if (sys->rng == nullptr || sys->ns == nullptr) { - // TODO(iphydf): Not quite right, but similar. - SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); - tox_options_free(default_options); - free(tox); - return nullptr; - } - - tox->rng = *sys->rng; - tox->ns = *sys->ns; + tox->sys = *sys; if (m_options.proxy_info.proxy_type != TCP_PROXY_NONE) { if (tox_options_get_proxy_port(opts) == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_PORT); tox_options_free(default_options); - free(tox); + mem_delete(sys->mem, tox); return nullptr; } @@ -773,33 +766,33 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) const char *const proxy_host = tox_options_get_proxy_host(opts); if (proxy_host == nullptr - || !addr_resolve_or_parse_ip(&tox->ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) { + || !addr_resolve_or_parse_ip(tox->sys.ns, proxy_host, &m_options.proxy_info.ip_port.ip, nullptr)) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_PROXY_BAD_HOST); // TODO(irungentoo): TOX_ERR_NEW_PROXY_NOT_FOUND if domain. tox_options_free(default_options); - free(tox); + mem_delete(sys->mem, tox); return nullptr; } m_options.proxy_info.ip_port.port = net_htons(tox_options_get_proxy_port(opts)); } - tox->mono_time = mono_time_new(sys->mono_time_callback, sys->mono_time_user_data); + tox->mono_time = mono_time_new(tox->sys.mem, sys->mono_time_callback, sys->mono_time_user_data); if (tox->mono_time == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); tox_options_free(default_options); - free(tox); + mem_delete(sys->mem, tox); return nullptr; } if (tox_options_get_experimental_thread_safety(opts)) { - tox->mutex = (pthread_mutex_t *)calloc(1, sizeof(pthread_mutex_t)); + tox->mutex = (pthread_mutex_t *)mem_alloc(sys->mem, sizeof(pthread_mutex_t)); if (tox->mutex == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); tox_options_free(default_options); - free(tox); + mem_delete(sys->mem, tox); return nullptr; } @@ -816,7 +809,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) tox_lock(tox); Messenger_Error m_error; - tox->m = new_messenger(tox->mono_time, &tox->rng, &tox->ns, &m_options, &m_error); + tox->m = new_messenger(tox->mono_time, tox->sys.mem, tox->sys.rng, tox->sys.ns, &m_options, &m_error); if (tox->m == nullptr) { if (m_error == MESSENGER_ERROR_PORT) { @@ -827,7 +820,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); } - mono_time_free(tox->mono_time); + mono_time_free(tox->sys.mem, tox->mono_time); tox_options_free(default_options); tox_unlock(tox); @@ -835,15 +828,15 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) pthread_mutex_destroy(tox->mutex); } - free(tox->mutex); - free(tox); + mem_delete(sys->mem, tox->mutex); + mem_delete(sys->mem, tox); return nullptr; } if (new_groupchats(tox->mono_time, tox->m) == nullptr) { kill_messenger(tox->m); - mono_time_free(tox->mono_time); + mono_time_free(tox->sys.mem, tox->mono_time); tox_options_free(default_options); tox_unlock(tox); @@ -851,8 +844,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) pthread_mutex_destroy(tox->mutex); } - free(tox->mutex); - free(tox); + mem_delete(sys->mem, tox->mutex); + mem_delete(sys->mem, tox); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); return nullptr; @@ -928,15 +921,15 @@ void tox_kill(Tox *tox) LOGGER_ASSERT(tox->m->log, tox->m->msi_packet == nullptr, "Attempted to kill tox while toxav is still alive"); kill_groupchats(tox->m->conferences_object); kill_messenger(tox->m); - mono_time_free(tox->mono_time); + mono_time_free(tox->sys.mem, tox->mono_time); tox_unlock(tox); if (tox->mutex != nullptr) { pthread_mutex_destroy(tox->mutex); - free(tox->mutex); + mem_delete(tox->sys.mem, tox->mutex); } - free(tox); + mem_delete(tox->sys.mem, tox); } static uint32_t end_size(void) @@ -1006,11 +999,11 @@ static int32_t resolve_bootstrap_node(Tox *tox, const char *host, uint16_t port, return -1; } - const int32_t count = net_getipport(host, root, TOX_SOCK_DGRAM); + const int32_t count = net_getipport(tox->sys.mem, host, root, TOX_SOCK_DGRAM); if (count < 1) { LOGGER_DEBUG(tox->m->log, "could not resolve bootstrap node '%s'", host); - net_freeipport(*root); + net_freeipport(tox->sys.mem, *root); SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); return -1; } @@ -1054,7 +1047,7 @@ bool tox_bootstrap(Tox *tox, const char *host, uint16_t port, const uint8_t *pub tox_unlock(tox); - net_freeipport(root); + net_freeipport(tox->sys.mem, root); if (count == 0 || !onion_success || !udp_success) { LOGGER_DEBUG(tox->m->log, "bootstrap node '%s' resolved to %d IP_Ports%s (onion: %s, UDP: %s)", @@ -1091,7 +1084,7 @@ bool tox_add_tcp_relay(Tox *tox, const char *host, uint16_t port, const uint8_t tox_unlock(tox); - net_freeipport(root); + net_freeipport(tox->sys.mem, root); if (count == 0) { SET_ERROR_PARAMETER(error, TOX_ERR_BOOTSTRAP_BAD_HOST); @@ -1944,7 +1937,7 @@ uint32_t tox_file_send(Tox *tox, uint32_t friend_number, uint32_t kind, uint64_t if (file_id == nullptr) { /* Tox keys are 32 bytes like FILE_ID_LENGTH. */ - new_symmetric_key(&tox->rng, f_id); + new_symmetric_key(tox->sys.rng, f_id); file_id = f_id; } @@ -2099,7 +2092,7 @@ uint32_t tox_conference_new(Tox *tox, Tox_Err_Conference_New *error) { assert(tox != nullptr); tox_lock(tox); - const int ret = add_groupchat(tox->m->conferences_object, &tox->rng, GROUPCHAT_TYPE_TEXT); + const int ret = add_groupchat(tox->m->conferences_object, tox->sys.rng, GROUPCHAT_TYPE_TEXT); tox_unlock(tox); if (ret == -1) { @@ -4580,3 +4573,8 @@ bool tox_group_mod_kick_peer(const Tox *tox, uint32_t group_number, uint32_t pee #endif /* VANILLA_NACL */ +const Tox_System *tox_get_system(Tox *tox) +{ + assert(tox != nullptr); + return &tox->sys; +} diff --git a/toxcore/tox.h b/toxcore/tox.h index fd1901f69c..d03e2b19b9 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -684,8 +684,8 @@ struct Tox_Options { bool experimental_thread_safety; /** - * Low level operating system functionality such as send/recv and random - * number generation. + * Low level operating system functionality such as send/recv, random + * number generation, and memory allocation. */ const Tox_System *operating_system; @@ -911,6 +911,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error); */ void tox_kill(Tox *tox); +const Tox_System *tox_get_system(Tox *tox); + /** * @brief Calculates the number of bytes required to store the tox instance with * tox_get_savedata. diff --git a/toxcore/tox_events.c b/toxcore/tox_events.c index 91a7767f7b..cae662e58e 100644 --- a/toxcore/tox_events.c +++ b/toxcore/tox_events.c @@ -4,6 +4,7 @@ #include "tox_events.h" +#include #include #include #include @@ -11,7 +12,9 @@ #include "bin_unpack.h" #include "ccompat.h" #include "events/events_alloc.h" +#include "mem.h" #include "tox.h" +#include "tox_private.h" /***************************************************** @@ -231,7 +234,7 @@ void tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes) bin_pack_obj(tox_events_bin_pack_handler, events, bytes, UINT32_MAX); } -Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size) +Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size) { Bin_Unpack *bu = bin_unpack_new(bytes, bytes_size); @@ -239,7 +242,7 @@ Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size) return nullptr; } - Tox_Events *events = (Tox_Events *)calloc(1, sizeof(Tox_Events)); + Tox_Events *events = (Tox_Events *)mem_alloc(sys->mem, sizeof(Tox_Events)); if (events == nullptr) { bin_unpack_free(bu); @@ -260,8 +263,11 @@ Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size) return events; } -bool tox_events_equal(const Tox_Events *a, const Tox_Events *b) +bool tox_events_equal(const Tox_System *sys, const Tox_Events *a, const Tox_Events *b) { + assert(sys != nullptr); + assert(sys->mem != nullptr); + const uint32_t a_size = tox_events_bytes_size(a); const uint32_t b_size = tox_events_bytes_size(b); @@ -269,12 +275,12 @@ bool tox_events_equal(const Tox_Events *a, const Tox_Events *b) return false; } - uint8_t *a_bytes = (uint8_t *)malloc(a_size); - uint8_t *b_bytes = (uint8_t *)malloc(b_size); + uint8_t *a_bytes = (uint8_t *)mem_balloc(sys->mem, a_size); + uint8_t *b_bytes = (uint8_t *)mem_balloc(sys->mem, b_size); if (a_bytes == nullptr || b_bytes == nullptr) { - free(b_bytes); - free(a_bytes); + mem_delete(sys->mem, b_bytes); + mem_delete(sys->mem, a_bytes); return false; } @@ -283,8 +289,8 @@ bool tox_events_equal(const Tox_Events *a, const Tox_Events *b) const bool ret = memcmp(a_bytes, b_bytes, a_size) == 0; - free(b_bytes); - free(a_bytes); + mem_delete(sys->mem, b_bytes); + mem_delete(sys->mem, a_bytes); return ret; } diff --git a/toxcore/tox_events.h b/toxcore/tox_events.h index f33a71b29c..e868d89098 100644 --- a/toxcore/tox_events.h +++ b/toxcore/tox_events.h @@ -343,9 +343,9 @@ void tox_events_free(Tox_Events *events); uint32_t tox_events_bytes_size(const Tox_Events *events); void tox_events_get_bytes(const Tox_Events *events, uint8_t *bytes); -Tox_Events *tox_events_load(const uint8_t *bytes, uint32_t bytes_size); +Tox_Events *tox_events_load(const Tox_System *sys, const uint8_t *bytes, uint32_t bytes_size); -bool tox_events_equal(const Tox_Events *a, const Tox_Events *b); +bool tox_events_equal(const Tox_System *sys, const Tox_Events *a, const Tox_Events *b); #ifdef __cplusplus } diff --git a/toxcore/tox_events_fuzz_test.cc b/toxcore/tox_events_fuzz_test.cc index 6dbfbb3595..ab1acb64ca 100644 --- a/toxcore/tox_events_fuzz_test.cc +++ b/toxcore/tox_events_fuzz_test.cc @@ -1,13 +1,33 @@ #include "tox_events.h" #include +#include #include +#include "../testing/fuzzing/fuzz_support.h" + namespace { -void TestUnpack(const uint8_t *data, size_t size) +void TestUnpack(Fuzz_Data data) { - Tox_Events *events = tox_events_load(data, size); + // 2 bytes: size of the events data + CONSUME_OR_RETURN(const uint8_t *events_size_bytes, data, sizeof(uint16_t)); + uint16_t events_size; + std::memcpy(&events_size, events_size_bytes, sizeof(uint16_t)); + + // events_size bytes: events data (max 64K) + CONSUME_OR_RETURN(const uint8_t *events_data, data, events_size); + + if (data.size == 0) { + // If there's no more input, no malloc failure paths can possibly be + // tested, so we ignore this input. + return; + } + + // rest of the fuzz data is input for malloc + Fuzz_System sys{data}; + + Tox_Events *events = tox_events_load(sys.sys.get(), events_data, events_size); if (events) { std::vector packed(tox_events_bytes_size(events)); tox_events_get_bytes(events, packed.data()); @@ -20,6 +40,6 @@ void TestUnpack(const uint8_t *data, size_t size) extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - TestUnpack(data, size); + TestUnpack(Fuzz_Data(data, size)); return 0; } diff --git a/toxcore/tox_events_test.cc b/toxcore/tox_events_test.cc index 40a78e962d..5de29b5e48 100644 --- a/toxcore/tox_events_test.cc +++ b/toxcore/tox_events_test.cc @@ -6,29 +6,32 @@ #include #include "crypto_core.h" +#include "tox_private.h" namespace { TEST(ToxEvents, UnpackRandomDataDoesntCrash) { - const Random *rng = system_random(); - ASSERT_NE(rng, nullptr); + const Tox_System sys = tox_default_system(); + ASSERT_NE(sys.rng, nullptr); std::array data; - random_bytes(rng, data.data(), data.size()); - tox_events_free(tox_events_load(data.data(), data.size())); + random_bytes(sys.rng, data.data(), data.size()); + tox_events_free(tox_events_load(&sys, data.data(), data.size())); } TEST(ToxEvents, UnpackEmptyDataFails) { + const Tox_System sys = tox_default_system(); std::array data; - Tox_Events *events = tox_events_load(data.end(), 0); + Tox_Events *events = tox_events_load(&sys, data.end(), 0); EXPECT_EQ(events, nullptr); } TEST(ToxEvents, UnpackEmptyArrayCreatesEmptyEvents) { + const Tox_System sys = tox_default_system(); std::array data{0x90}; // empty msgpack array - Tox_Events *events = tox_events_load(data.data(), data.size()); + Tox_Events *events = tox_events_load(&sys, data.data(), data.size()); ASSERT_NE(events, nullptr); EXPECT_EQ(tox_events_get_conference_connected_size(events), 0); tox_events_free(events); @@ -44,9 +47,10 @@ TEST(ToxEvents, NullEventsPacksToEmptyArray) TEST(ToxEvents, PackedEventsCanBeUnpacked) { + const Tox_System sys = tox_default_system(); // [[0, 1]] == Tox_Self_Connection_Status { .connection_status = TOX_CONNECTION_TCP } std::array packed{0x91, 0x92, 0xcc, 0x00, 0xcc, 0x01}; - Tox_Events *events = tox_events_load(packed.data(), packed.size()); + Tox_Events *events = tox_events_load(&sys, packed.data(), packed.size()); ASSERT_NE(events, nullptr); std::array bytes; ASSERT_EQ(tox_events_bytes_size(events), bytes.size()); @@ -57,8 +61,9 @@ TEST(ToxEvents, PackedEventsCanBeUnpacked) TEST(ToxEvents, DealsWithHugeMsgpackArrays) { + const Tox_System sys = tox_default_system(); std::vector data{0xdd, 0xff, 0xff, 0xff, 0xff}; - EXPECT_EQ(tox_events_load(data.data(), data.size()), nullptr); + EXPECT_EQ(tox_events_load(&sys, data.data(), data.size()), nullptr); } } // namespace diff --git a/toxcore/tox_private.c b/toxcore/tox_private.c index 847e96d426..72a93358a5 100644 --- a/toxcore/tox_private.c +++ b/toxcore/tox_private.c @@ -11,6 +11,7 @@ #include #include "ccompat.h" +#include "mem.h" #include "network.h" #include "tox_struct.h" @@ -28,6 +29,7 @@ Tox_System tox_default_system(void) nullptr, // mono_time_user_data system_random(), system_network(), + system_memory(), }; return sys; } @@ -115,11 +117,11 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip IP_Port *root; - const int32_t count = net_getipport(ip, &root, TOX_SOCK_DGRAM); + const int32_t count = net_getipport(tox->sys.mem, ip, &root, TOX_SOCK_DGRAM); if (count < 1) { SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_BAD_IP); - net_freeipport(root); + net_freeipport(tox->sys.mem, root); tox_unlock(tox); return false; } @@ -136,7 +138,7 @@ bool tox_dht_get_nodes(const Tox *tox, const uint8_t *public_key, const char *ip tox_unlock(tox); - net_freeipport(root); + net_freeipport(tox->sys.mem, root); if (!success) { SET_ERROR_PARAMETER(error, TOX_ERR_DHT_GET_NODES_FAIL); diff --git a/toxcore/tox_private.h b/toxcore/tox_private.h index 71d7a97601..c82357170e 100644 --- a/toxcore/tox_private.h +++ b/toxcore/tox_private.h @@ -23,6 +23,7 @@ struct Tox_System { void *mono_time_user_data; const struct Random *rng; const struct Network *ns; + const struct Memory *mem; }; Tox_System tox_default_system(void); diff --git a/toxcore/tox_struct.h b/toxcore/tox_struct.h index 8b95d83bbc..b298269af9 100644 --- a/toxcore/tox_struct.h +++ b/toxcore/tox_struct.h @@ -7,6 +7,7 @@ #define C_TOXCORE_TOXCORE_TOX_STRUCT_H #include "Messenger.h" +#include "mem.h" #include "tox.h" #include "tox_private.h" @@ -17,8 +18,7 @@ extern "C" { struct Tox { Messenger *m; Mono_Time *mono_time; - Random rng; - Network ns; + Tox_System sys; pthread_mutex_t *mutex; tox_log_cb *log_callback; diff --git a/toxcore/util.c b/toxcore/util.c index 402977a680..3b3779bd7c 100644 --- a/toxcore/util.c +++ b/toxcore/util.c @@ -24,7 +24,7 @@ bool is_power_of_2(uint64_t x) return x != 0 && (x & (~x + 1)) == x; } -void free_uint8_t_pointer_array(uint8_t **ary, size_t n_items) +void free_uint8_t_pointer_array(const Memory *mem, uint8_t **ary, size_t n_items) { if (ary == nullptr) { return; @@ -32,11 +32,11 @@ void free_uint8_t_pointer_array(uint8_t **ary, size_t n_items) for (size_t i = 0; i < n_items; ++i) { if (ary[i] != nullptr) { - free(ary[i]); + mem_delete(mem, ary[i]); } } - free(ary); + mem_delete(mem, ary); } uint16_t data_checksum(const uint8_t *data, uint32_t length) diff --git a/toxcore/util.h b/toxcore/util.h index 588feb5694..44091b3622 100644 --- a/toxcore/util.h +++ b/toxcore/util.h @@ -16,6 +16,7 @@ #include #include "attributes.h" +#include "mem.h" #ifdef __cplusplus extern "C" { @@ -24,8 +25,8 @@ extern "C" { bool is_power_of_2(uint64_t x); /** @brief Frees all pointers in a uint8_t pointer array, as well as the array itself. */ -nullable(1) -void free_uint8_t_pointer_array(uint8_t **ary, size_t n_items); +non_null(1) nullable(2) +void free_uint8_t_pointer_array(const Memory *mem, uint8_t **ary, size_t n_items); /** Returns -1 if failed or 0 if success */ non_null() int create_recursive_mutex(pthread_mutex_t *mutex);