From d194b004d80a52995562f70966a885dd3b2c413b 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. --- auto_tests/announce_test.c | 7 +- auto_tests/forwarding_test.c | 6 +- auto_tests/onion_test.c | 21 +++-- other/DHT_bootstrap.c | 3 +- other/bootstrap_daemon/src/tox-bootstrapd.c | 5 +- testing/Messenger_test.c | 2 +- testing/fuzzing/BUILD.bazel | 4 + toxcore/BUILD.bazel | 10 +++ toxcore/DHT.c | 23 +++--- toxcore/DHT.h | 7 +- toxcore/DHT_test.cc | 3 +- toxcore/Messenger.c | 8 +- toxcore/Messenger.h | 4 +- toxcore/announce.c | 8 +- toxcore/announce.h | 3 +- toxcore/mem.c | 65 ++++++++++++++++ toxcore/mem.h | 49 ++++++++++++ toxcore/tox.c | 85 ++++++++++----------- toxcore/tox_private.c | 2 + toxcore/tox_private.h | 1 + toxcore/tox_struct.h | 2 + 21 files changed, 236 insertions(+), 82 deletions(-) create mode 100644 toxcore/mem.c create mode 100644 toxcore/mem.h 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..e68ff585b2b 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,7 +126,7 @@ 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); @@ -132,7 +134,7 @@ static Forwarding_Subtox *new_forwarding_subtox(bool no_udp, uint32_t *index, ui 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..1e7286566c6 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); @@ -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..f1b10a24463 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(); diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c index d12caf9bd2a..9cd7c92d035 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"); 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..8dce9f1e945 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; } @@ -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)); @@ -2606,7 +2609,8 @@ 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) { @@ -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; 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/Messenger.c b/toxcore/Messenger.c index 118c7d946c2..ad36596f350 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); @@ -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; 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/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/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/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;