From e9785f3c0042229e9d70b9705a0d2a1dfd594531 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. --- CMakeLists.txt | 2 + auto_tests/TCP_test.c | 38 ++++++--- auto_tests/announce_test.c | 7 +- auto_tests/forwarding_test.c | 8 +- auto_tests/onion_test.c | 23 +++--- other/DHT_bootstrap.c | 5 +- other/bootstrap_daemon/src/tox-bootstrapd.c | 8 +- testing/Messenger_test.c | 2 +- testing/fuzzing/BUILD.bazel | 4 + toxcore/BUILD.bazel | 10 +++ toxcore/DHT.c | 69 +++++++++-------- toxcore/DHT.h | 7 +- toxcore/DHT_test.cc | 3 +- toxcore/Makefile.inc | 2 + toxcore/Messenger.c | 15 ++-- toxcore/Messenger.h | 4 +- toxcore/TCP_connection.c | 17 +++-- toxcore/TCP_connection.h | 5 +- toxcore/TCP_server.c | 28 +++---- toxcore/TCP_server.h | 4 +- toxcore/announce.c | 8 +- toxcore/announce.h | 3 +- toxcore/group_chats.c | 3 +- toxcore/group_common.h | 1 + toxcore/mem.c | 65 ++++++++++++++++ toxcore/mem.h | 49 ++++++++++++ toxcore/net_crypto.c | 7 +- toxcore/net_crypto.h | 3 +- toxcore/tox.c | 85 ++++++++++----------- toxcore/tox_private.c | 2 + toxcore/tox_private.h | 1 + toxcore/tox_struct.h | 2 + 32 files changed, 337 insertions(+), 153 deletions(-) create mode 100644 toxcore/mem.c create mode 100644 toxcore/mem.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f6228e4eb8b..24a46320860 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 diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c index 33bbe0e22c2..fe432e565a7 100644 --- a/auto_tests/TCP_test.c +++ b/auto_tests/TCP_test.c @@ -48,6 +48,11 @@ 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); + 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); @@ -302,11 +306,14 @@ static void test_some(void) 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); 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."); @@ -492,12 +499,15 @@ static void test_client(void) 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); 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."); @@ -699,22 +709,25 @@ static void test_tcp_connection(void) 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); 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; @@ -808,6 +821,9 @@ static void test_tcp_connection2(void) 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); tcp_oobdata_callback_called = 0; tcp_data_callback_called = 0; @@ -815,17 +831,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; diff --git a/auto_tests/announce_test.c b/auto_tests/announce_test.c index c31d5ca75da..37201ed1b7c 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); + 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: */ diff --git a/auto_tests/forwarding_test.c b/auto_tests/forwarding_test.c index bc912fb0535..fab761cd6b8 100644 --- a/auto_tests/forwarding_test.c +++ b/auto_tests/forwarding_test.c @@ -116,6 +116,8 @@ static Forwarding_Subtox *new_forwarding_subtox(bool no_udp, uint32_t *index, ui ck_assert(rng != nullptr); const Network *ns = system_network(); ck_assert(ns != nullptr); + const Memory *mem = system_memory(); + ck_assert(mem != nullptr); if (no_udp) { subtox->net = new_networking_no_udp(subtox->log, ns); @@ -124,15 +126,15 @@ static Forwarding_Subtox *new_forwarding_subtox(bool no_udp, uint32_t *index, ui subtox->net = new_networking_ex(subtox->log, 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; diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c index 02a15b2247c..1552333e1a8 100644 --- a/auto_tests/onion_test.c +++ b/auto_tests/onion_test.c @@ -224,20 +224,23 @@ 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); 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, mono_time1, rng, new_dht(log1, mem, rng, ns, mono_time1, new_networking(log1, ns, &ip, 36567), true, false)); + Onion *onion2 = new_onion(log2, mono_time2, rng, new_dht(log2, mem, rng, ns, mono_time2, new_networking(log2, 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); @@ -333,7 +336,7 @@ static void test_basic(void) Mono_Time *mono_time3 = mono_time_new(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, mono_time3, rng, new_dht(log3, mem, rng, ns, mono_time3, new_networking(log3, ns, &ip, 36569), true, false)); ck_assert_msg((onion3 != nullptr), "Onion failed initializing."); random_nonce(rng, nonce); @@ -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; @@ -437,7 +440,7 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) 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); @@ -471,7 +474,7 @@ static Onions *new_onions(const Random *rng, uint16_t port, uint32_t *index) } 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, 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); @@ -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); } diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c index 4128992e4af..da703a760e9 100644 --- a/other/DHT_bootstrap.c +++ b/other/DHT_bootstrap.c @@ -148,7 +148,8 @@ int main(int argc, char *argv[]) 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); + const Memory *mem = system_memory(); + DHT *dht = new_dht(logger, mem, 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); Forwarding *forwarding = new_forwarding(logger, rng, mono_time, dht); GC_Announces_List *gc_announces_list = new_gca_list(); @@ -173,7 +174,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/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index d12caf9bd2a..4bc5dc650ca 100644 --- a/other/bootstrap_daemon/src/tox-bootstrapd.c +++ b/other/bootstrap_daemon/src/tox-bootstrapd.c @@ -322,8 +322,9 @@ int main(int argc, char *argv[]) mono_time_update(mono_time); + const Memory *mem = system_memory(); 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"); @@ -350,7 +351,7 @@ 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"); @@ -476,7 +477,8 @@ int main(int argc, char *argv[]) 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); diff --git a/testing/Messenger_test.c b/testing/Messenger_test.c index b36d2a15585..d9a9f30af72 100644 --- a/testing/Messenger_test.c +++ b/testing/Messenger_test.c @@ -102,7 +102,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, system_memory(), 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 9f8c0b96072..386516d72bf 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/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 730b84e974a..a5d1ce53d37 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -15,6 +15,14 @@ cc_library( visibility = ["//c-toxcore:__subpackages__"], ) +cc_library( + name = "mem", + srcs = ["mem.c"], + hdrs = ["mem.h"], + visibility = ["//c-toxcore:__subpackages__"], + deps = [":attributes"], +) + cc_library( name = "ccompat", srcs = ["ccompat.c"], @@ -315,6 +323,7 @@ cc_library( ":ccompat", ":crypto_core", ":logger", + ":mem", ":mono_time", ":network", ":ping_array", @@ -766,6 +775,7 @@ cc_library( ":group", ":group_moderation", ":logger", + ":mem", ":mono_time", ":network", "//c-toxcore/toxencryptsave:defines", diff --git a/toxcore/DHT.c b/toxcore/DHT.c index 91f0e0ae476..04cf1551a04 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_malloc(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_free(mem, encrypted); return -1; } if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) { - free(encrypted); + mem_free(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_free(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_calloc(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_free(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_realloc(dht->mem, dht->friends_list, sizeof(DHT_Friend) * (dht->num_friends + 1)); 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_free(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_realloc(dht->mem, dht->friends_list, sizeof(DHT_Friend) * dht->num_friends); 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_calloc(dht->mem, list_count * 2, sizeof(Client_data *)); + IPPTsPng **assoc_list = (IPPTsPng **)mem_calloc(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_free(dht->mem, assoc_list); + mem_free(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_free(dht->mem, assoc_list); + mem_free(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_calloc(mem, 1, sizeof(DHT)); if (dht == nullptr) { return nullptr; @@ -2625,6 +2629,7 @@ 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; @@ -2723,10 +2728,10 @@ void kill_dht(DHT *dht) 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); + mem_free(dht->mem, dht->friends_list); + mem_free(dht->mem, dht->loaded_nodes_list); crypto_memzero(dht->self_secret_key, sizeof(dht->self_secret_key)); - free(dht); + mem_free(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_calloc(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_free(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_free(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_free(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_calloc(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 86ac4f9d406..95f442e79fa 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 3014c0b2565..44e241790b0 100644 --- a/toxcore/DHT_test.cc +++ b/toxcore/DHT_test.cc @@ -191,8 +191,9 @@ TEST(AnnounceNodes, SetAndTest) Mono_Time *mono_time = mono_time_new(nullptr, nullptr); const Random *rng = system_random(); const Network *ns = system_network(); + const Memory *mem = system_memory(); Networking_Core *net = new_networking_no_udp(log, ns); - DHT *dht = new_dht(log, rng, ns, mono_time, net, true, true); + 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]; diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index e5f0ddf91dd..70df82b39e6 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 118c7d946c2..707ac416561 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -3502,7 +3502,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; @@ -3519,6 +3520,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network } m->mono_time = mono_time; + m->mem = mem; m->rng = rng; m->ns = ns; @@ -3567,7 +3569,7 @@ 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); @@ -3577,7 +3579,7 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network 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); @@ -3605,7 +3607,7 @@ 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; @@ -3661,8 +3663,9 @@ Messenger *new_messenger(Mono_Time *mono_time, const Random *rng, const Network #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); diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 82798152774..cabb2af89d8 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_connection.c b/toxcore/TCP_connection.c index 4c71f366b33..a1d7e059a71 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; @@ -73,16 +74,16 @@ uint32_t tcp_connections_count(const TCP_Connections *tcp_c) * @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_free(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_realloc(mem, *array, num * sizeof(TCP_Connection_to)); 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; @@ -221,7 +222,7 @@ 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); + realloc_TCP_Connection_to(tcp_c->mem, &tcp_c->connections, tcp_c->connections_length); } return 0; @@ -1580,9 +1581,8 @@ 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) { if (secret_key == nullptr) { return nullptr; @@ -1595,6 +1595,7 @@ TCP_Connections *new_tcp_connections( } temp->logger = logger; + temp->mem = mem; temp->rng = rng; temp->mono_time = mono_time; temp->ns = ns; diff --git a/toxcore/TCP_connection.h b/toxcore/TCP_connection.h index 0434a73eb0a..f01e7054459 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 ecd557d1b27..662b02328d0 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,8 +118,8 @@ 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, + TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)mem_realloc( + tcp_server->mem, tcp_server->accepted_connection_array, new_size * sizeof(TCP_Secure_Connection)); if (new_connections == nullptr) { @@ -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_free(tcp_server->mem, tcp_server->accepted_connection_array); tcp_server->accepted_connection_array = nullptr; tcp_server->size_accepted_connections = 0; } @@ -935,7 +936,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 +950,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_calloc(mem, 1, sizeof(TCP_Server)); if (temp == nullptr) { LOGGER_ERROR(logger, "TCP server allocation failed"); @@ -957,14 +958,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_calloc(mem, num_sockets, sizeof(Socket)); if (temp->socks_listening == nullptr) { LOGGER_ERROR(logger, "socket allocation failed"); - free(temp); + mem_free(mem, temp); return nullptr; } @@ -973,8 +975,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_free(mem, temp->socks_listening); + mem_free(mem, temp); return nullptr; } @@ -1006,8 +1008,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_free(mem, temp->socks_listening); + mem_free(mem, temp); return nullptr; } @@ -1406,6 +1408,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_free(tcp_server->mem, tcp_server->socks_listening); + mem_free(tcp_server->mem, tcp_server); } diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h index 2224938a099..090e821607d 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 647bd21ea39..95678818bb7 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; diff --git a/toxcore/announce.h b/toxcore/announce.h index e680da68b62..bbd7a72b452 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/group_chats.c b/toxcore/group_chats.c index f9cb2d18fbb..784c7e16551 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) { @@ -7332,6 +7332,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); diff --git a/toxcore/group_common.h b/toxcore/group_common.h index ef901e8a3a9..34d67dc8d62 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/mem.c b/toxcore/mem.c new file mode 100644 index 00000000000..fc6abb2d838 --- /dev/null +++ b/toxcore/mem.c @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. + */ + +#include "mem.h" + +#include + +non_null() +static void *sys_malloc(void *obj, uint32_t size) +{ + return malloc(size); +} + +non_null() +static void *sys_calloc(void *obj, uint32_t nmemb, uint32_t size) +{ + return calloc(nmemb, size); +} + +non_null(1) nullable(2) +static void *sys_realloc(void *obj, void *ptr, uint32_t size) +{ + return realloc(ptr, size); +} + +non_null(1) nullable(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_malloc(const Memory *mem, uint32_t size) +{ + return mem->funcs->malloc(mem->obj, size); +} + +void *mem_calloc(const Memory *mem, uint32_t nmemb, uint32_t size) +{ + return mem->funcs->calloc(mem->obj, nmemb, size); +} + +void *mem_realloc(const Memory *mem, void *ptr, uint32_t size) +{ + return mem->funcs->realloc(mem->obj, ptr, size); +} + +void mem_free(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 00000000000..ad148cd6f13 --- /dev/null +++ b/toxcore/mem.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2016-2018 The TokTok team. + * Copyright © 2013 Tox project. + */ + +/** + * Datatypes, functions and includes for the core networking. + */ +#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); + +non_null() void *mem_malloc(const Memory *mem, uint32_t size); +non_null() void *mem_calloc(const Memory *mem, uint32_t nmemb, uint32_t size); +non_null(1) nullable(2) void *mem_realloc(const Memory *mem, void *ptr, uint32_t size); +non_null(1) nullable(2) void mem_free(const Memory *mem, void *ptr); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 71f6e39e647..39b7addee91 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; @@ -3109,7 +3110,8 @@ 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; @@ -3122,11 +3124,12 @@ Net_Crypto *new_net_crypto(const Logger *log, const Random *rng, const Network * } 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); diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 0c3dfd0d45a..ac6a0b59cbd 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/tox.c b/toxcore/tox.c index 3f7dcc439d6..9b9ff338362 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_calloc(sys->mem, 1, 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,20 @@ 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_free(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->mem = *sys->mem; 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_free(sys->mem, tox); return nullptr; } @@ -777,7 +772,7 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) 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_free(sys->mem, tox); return nullptr; } @@ -789,17 +784,17 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) if (tox->mono_time == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); tox_options_free(default_options); - free(tox); + mem_free(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_calloc(sys->mem, 1, sizeof(pthread_mutex_t)); if (tox->mutex == nullptr) { SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); tox_options_free(default_options); - free(tox); + mem_free(sys->mem, tox); return nullptr; } @@ -816,7 +811,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->mem, &tox->rng, &tox->ns, &m_options, &m_error); if (tox->m == nullptr) { if (m_error == MESSENGER_ERROR_PORT) { @@ -835,8 +830,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) pthread_mutex_destroy(tox->mutex); } - free(tox->mutex); - free(tox); + mem_free(sys->mem, tox->mutex); + mem_free(sys->mem, tox); return nullptr; } @@ -851,8 +846,8 @@ Tox *tox_new(const struct Tox_Options *options, Tox_Err_New *error) pthread_mutex_destroy(tox->mutex); } - free(tox->mutex); - free(tox); + mem_free(sys->mem, tox->mutex); + mem_free(sys->mem, tox); SET_ERROR_PARAMETER(error, TOX_ERR_NEW_MALLOC); return nullptr; @@ -933,10 +928,10 @@ void tox_kill(Tox *tox) if (tox->mutex != nullptr) { pthread_mutex_destroy(tox->mutex); - free(tox->mutex); + mem_free(&tox->mem, tox->mutex); } - free(tox); + mem_free(&tox->mem, tox); } static uint32_t end_size(void) diff --git a/toxcore/tox_private.c b/toxcore/tox_private.c index 847e96d4262..67533603c76 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; } diff --git a/toxcore/tox_private.h b/toxcore/tox_private.h index 71d7a976018..c82357170e6 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 8b95d83bbce..ba65786a888 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" @@ -19,6 +20,7 @@ struct Tox { Mono_Time *mono_time; Random rng; Network ns; + Memory mem; pthread_mutex_t *mutex; tox_log_cb *log_callback;