diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 90216a8..d10fb9d 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,9 @@ SET(SOURCES utils/mac_utils.c include/mac_utils.h + utils/memory_utils.c + include/memory_utils.h + include/tcpsocket.h network/tcpsocket.c @@ -61,6 +64,9 @@ SET(SOURCES_TEST_STORAGE utils/mac_utils.c include/mac_utils.h + utils/memory_utils.c + include/memory_utils.h + storage/datastorage.c include/datastorage.h diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c index 7ce7d8c..00fddc7 100644 --- a/src/crypto/crypto.c +++ b/src/crypto/crypto.c @@ -3,6 +3,7 @@ #include +#include "memory_utils.h" #include "crypto.h" #define GCRY_CIPHER GCRY_CIPHER_AES128 // Pick the cipher here @@ -64,7 +65,7 @@ char *gcrypt_encrypt_msg(char *msg, size_t msg_length, int *out_length) { if (0U != (msg_length & 0xfU)) msg_length += 0x10U - (msg_length & 0xfU); - char *out = malloc(msg_length); + char *out = dawn_malloc(msg_length); if (!out){ fprintf(stderr, "gcry_cipher_encrypt error: not enought memory\n"); return NULL; @@ -85,7 +86,7 @@ char *gcrypt_decrypt_msg(char *msg, size_t msg_length) { if (0U != (msg_length & 0xfU)) msg_length += 0x10U - (msg_length & 0xfU); - char *out_buffer = malloc(msg_length); + char *out_buffer = dawn_malloc(msg_length); if (!out_buffer){ fprintf(stderr, "gcry_cipher_decrypt error: not enought memory\n"); return NULL; @@ -95,17 +96,17 @@ char *gcrypt_decrypt_msg(char *msg, size_t msg_length) { fprintf(stderr, "gcry_cipher_decrypt failed: %s/%s\n", gcry_strsource(gcry_error_handle), gcry_strerror(gcry_error_handle)); - free(out_buffer); + dawn_free(out_buffer); return NULL; } - char *out = malloc(strlen(out_buffer) + 1); + char *out = dawn_malloc(strlen(out_buffer) + 1); if (!out){ - free(out_buffer); + dawn_free(out_buffer); fprintf(stderr, "gcry_cipher_decrypt error: not enought memory\n"); return NULL; } strcpy(out, out_buffer); - free(out_buffer); + dawn_free(out_buffer); return out; } diff --git a/src/include/memory_utils.h b/src/include/memory_utils.h new file mode 100644 index 0000000..16de90a --- /dev/null +++ b/src/include/memory_utils.h @@ -0,0 +1,45 @@ +#ifndef DAWN_UTIL_MEMORY +#define DAWN_UTIL_MEMORY + +#include + +enum dawn_memop +{ + DAWN_MALLOC, + DAWN_CALLOC, + DAWN_REALLOC, + DAWN_MEMREG, + DAWN_MEMUNREG, + DAWN_FREE +}; + +#define DAWN_MEMORY_AUDITING + +#ifdef DAWN_MEMORY_AUDITING +#define dawn_malloc(size) dawn_memory_alloc(DAWN_MALLOC, __FILE__, __LINE__, 1, size, NULL) +#define dawn_calloc(nmemb, size) dawn_memory_alloc(DAWN_CALLOC, __FILE__, __LINE__, nmemb, size, NULL) +#define dawn_realloc(ptr, size) dawn_memory_alloc(DAWN_REALLOC, __FILE__, __LINE__, 1, size, ptr) +#define dawn_free(p) dawn_memory_free(DAWN_FREE, __FILE__, __LINE__, p) + +#define dawn_regmem(p) dawn_memory_register(DAWN_MEMREG, __FILE__, __LINE__, 0, p) +#define dawn_unregmem(p) dawn_memory_unregister(DAWN_MEMUNREG, __FILE__, __LINE__, p) +#else +#define dawn_malloc(size) malloc(size) +#define dawn_calloc(nmemb, size) calloc(nmemb, size) +#define dawn_realloc(ptr, size) realloc(ptr, size) +#define dawn_free(p) free(p) + +#define dawn_regmem(p) +#define dawn_unregmem(p) +#endif + +void* dawn_memory_alloc(enum dawn_memop type, char* file, int line, size_t nmemb, size_t size, void *ptr); + +void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t size, void *ptr); + +void dawn_memory_free(enum dawn_memop type, char* file, int line, void* ptr); + +void dawn_memory_unregister(enum dawn_memop type, char* file, int line, void* ptr); + +void dawn_memory_audit(); +#endif diff --git a/src/main.c b/src/main.c index 57d38df..edcbd23 100644 --- a/src/main.c +++ b/src/main.c @@ -4,6 +4,7 @@ #include #include +#include "memory_utils.h" #include "datastorage.h" #include "networksocket.h" #include "ubus.h" @@ -30,7 +31,8 @@ void daemon_shutdown() { void signal_handler(int sig) { switch (sig) { case SIGHUP: - daemon_shutdown(); + //daemon_shutdown(); + dawn_memory_audit(); break; case SIGINT: daemon_shutdown(); diff --git a/src/network/networksocket.c b/src/network/networksocket.c index 8a25ca7..1f176bf 100644 --- a/src/network/networksocket.c +++ b/src/network/networksocket.c @@ -3,6 +3,7 @@ #include #include +#include "memory_utils.h" #include "multicastsocket.h" #include "broadcastsocket.h" #include "msghandler.h" @@ -68,6 +69,7 @@ void *receive_msg(void *args) { continue; } + // TODO: recv_string is a fixed array. Should test be here? if (recv_string == NULL) { return 0; } @@ -90,6 +92,7 @@ void *receive_msg_enc(void *args) { continue; } + // TODO: recv_string is a fixed array. Should test be here? if (recv_string == NULL) { return 0; } @@ -99,23 +102,23 @@ void *receive_msg_enc(void *args) { } recv_string[recv_string_len] = '\0'; - char *base64_dec_str = malloc(B64_DECODE_LEN(strlen(recv_string))); + char *base64_dec_str = dawn_malloc(B64_DECODE_LEN(strlen(recv_string))); if (!base64_dec_str){ - fprintf(stderr, "Received network error: not enought memory\n"); + fprintf(stderr, "Received network error: not enough memory\n"); return 0; } int base64_dec_length = b64_decode(recv_string, base64_dec_str, B64_DECODE_LEN(strlen(recv_string))); char *dec = gcrypt_decrypt_msg(base64_dec_str, base64_dec_length); if (!dec){ - free(base64_dec_str); - fprintf(stderr, "Received network error: not enought memory\n"); + dawn_free(base64_dec_str); + fprintf(stderr, "Received network error: not enough memory\n"); return 0; } printf("Received network message: %s\n", dec); - free(base64_dec_str); + dawn_free(base64_dec_str); handle_network_msg(dec); - free(dec); + dawn_free(dec); } } @@ -145,15 +148,15 @@ int send_string_enc(char *msg) { size_t msglen = strlen(msg); char *enc = gcrypt_encrypt_msg(msg, msglen + 1, &length_enc); if (!enc){ - fprintf(stderr, "sendto() error: not enought memory\n"); + fprintf(stderr, "sendto() error: not enough memory\n"); pthread_mutex_unlock(&send_mutex); exit(EXIT_FAILURE); } - char *base64_enc_str = malloc(B64_ENCODE_LEN(length_enc)); + char *base64_enc_str = dawn_malloc(B64_ENCODE_LEN(length_enc)); if (!base64_enc_str){ - free(enc); - fprintf(stderr, "sendto() error: not enought memory\n"); + dawn_free(enc); + fprintf(stderr, "sendto() error: not enough memory\n"); pthread_mutex_unlock(&send_mutex); exit(EXIT_FAILURE); } @@ -169,8 +172,8 @@ int send_string_enc(char *msg) { pthread_mutex_unlock(&send_mutex); exit(EXIT_FAILURE); } - free(base64_enc_str); - free(enc); + dawn_free(base64_enc_str); + dawn_free(enc); pthread_mutex_unlock(&send_mutex); return 0; } diff --git a/src/network/tcpsocket.c b/src/network/tcpsocket.c index bf62368..e044798 100644 --- a/src/network/tcpsocket.c +++ b/src/network/tcpsocket.c @@ -2,6 +2,7 @@ #include #include +#include "memory_utils.h" #include "msghandler.h" #include "crypto.h" #include "datastorage.h" @@ -15,7 +16,7 @@ LIST_HEAD(tcp_sock_list); struct network_con_s *tcp_list_contains_address(struct sockaddr_in entry); static struct uloop_fd server; -struct client *next_client = NULL; +static struct client *next_client = NULL; // TODO: Why here? Only used in sever_cb() struct client { struct sockaddr_in sin; @@ -26,13 +27,12 @@ struct client { }; static void client_close(struct ustream *s) { - struct client *cl = container_of(s, - struct client, s.stream); + struct client *cl = container_of(s, struct client, s.stream); fprintf(stderr, "Connection closed\n"); ustream_free(s); close(cl->s.fd.fd); - free(cl); + dawn_free(cl); } static void client_notify_write(struct ustream *s, int bytes) { @@ -61,7 +61,7 @@ static void client_to_server_close(struct ustream *s) { ustream_free(s); close(con->fd.fd); list_del(&con->list); - free(con); + dawn_free(con); } static void client_to_server_state(struct ustream *s) { @@ -82,7 +82,7 @@ static void client_read_cb(struct ustream *s, int bytes) { char *str, *str_tmp; int len = 0; uint32_t final_len = sizeof(uint32_t); // big enough to get msg length - str = malloc(final_len); + str = dawn_malloc(final_len); if (!str) { fprintf(stderr,"not enough memory (" STR_QUOTE(__LINE__) ")\n"); goto nofree; @@ -99,11 +99,11 @@ static void client_read_cb(struct ustream *s, int bytes) { } final_len = ntohl(*(uint32_t *)str) - final_len;//the final_len in headder includes header itself - str_tmp = realloc(str, final_len); + str_tmp = dawn_realloc(str, final_len); if (!str_tmp) { fprintf(stderr,"not enough memory (%" PRIu32 " @ " STR_QUOTE(__LINE__) ")\n", final_len); - goto out;//On failure, realloc returns a null pointer. The original pointer str remains valid - //and may need to be deallocated with free() or realloc(). + goto out;//On failure, dawn_realloc returns a null pointer. The original pointer str remains valid + //and may need to be deallocated. } str = str_tmp; @@ -119,25 +119,26 @@ static void client_read_cb(struct ustream *s, int bytes) { goto out; } handle_network_msg(dec); - free(dec); + dawn_free(dec); } else { handle_network_msg(str);//len of str is final_len } out: - free(str); + dawn_free(str); nofree: return; } static void server_cb(struct uloop_fd *fd, unsigned int events) { - struct client *cl; + struct client *cl; //MUSTDO: check free() of this unsigned int sl = sizeof(struct sockaddr_in); int sfd; if (!next_client) - next_client = calloc(1, sizeof(*next_client)); + next_client = dawn_calloc(1, sizeof(*next_client)); cl = next_client; + sfd = accept(server.fd, (struct sockaddr *) &cl->sin, &sl); if (sfd < 0) { fprintf(stderr, "Accept failed\n"); @@ -149,7 +150,7 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) { cl->s.stream.notify_state = client_notify_state; cl->s.stream.notify_write = client_notify_write; ustream_fd_init(&cl->s, sfd); - next_client = NULL; + next_client = NULL; // TODO: Why is this here? To avoid resetting if above return happens? fprintf(stderr, "New connection\n"); } @@ -187,7 +188,7 @@ static void connect_cb(struct uloop_fd *f, unsigned int events) { fprintf(stderr, "Connection failed (%s)\n", f->eof ? "EOF" : "ERROR"); close(entry->fd.fd); list_del(&entry->list); - free(entry); + dawn_free(entry); return; } @@ -213,6 +214,7 @@ int add_tcp_conncection(char *ipv4, int port) { serv_addr.sin_port = htons(port); struct network_con_s *tmp = tcp_list_contains_address(serv_addr); + dawn_regmem(tmp); if (tmp != NULL) { if(tmp->connected == true) { @@ -221,16 +223,16 @@ int add_tcp_conncection(char *ipv4, int port) { // Delete already existing entry close(tmp->fd.fd); list_del(&tmp->list); - free(tmp); + dawn_free(tmp); } } - struct network_con_s *tcp_entry = calloc(1, sizeof(struct network_con_s)); + struct network_con_s *tcp_entry = dawn_calloc(1, sizeof(struct network_con_s)); tcp_entry->fd.fd = usock(USOCK_TCP | USOCK_NONBLOCK, ipv4, port_str); tcp_entry->sock_addr = serv_addr; if (tcp_entry->fd.fd < 0) { - free(tcp_entry); + dawn_free(tcp_entry); return -1; } tcp_entry->fd.cb = connect_cb; @@ -255,9 +257,9 @@ void send_tcp(char *msg) { } uint32_t final_len = length_enc + sizeof(final_len); - char *final_str = malloc(final_len); + char *final_str = dawn_malloc(final_len); if (!final_str){ - free(enc); + dawn_free(enc); fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n"); return; } @@ -276,19 +278,19 @@ void send_tcp(char *msg) { ustream_free(&con->stream.stream); close(con->fd.fd); list_del(&con->list); - free(con); + dawn_free(con); } } } } - free(final_str); - free(enc); + dawn_free(final_str); + dawn_free(enc); } else { size_t msglen = strlen(msg) + 1; uint32_t final_len = msglen + sizeof(final_len); - char *final_str = malloc(final_len); + char *final_str = dawn_malloc(final_len); if (!final_str){ fprintf(stderr, "Ustream error: not enought memory (" STR_QUOTE(__LINE__) ")\n"); return; @@ -309,12 +311,12 @@ void send_tcp(char *msg) { ustream_free(&con->stream.stream); close(con->fd.fd); list_del(&con->list); - free(con); + dawn_free(con); } } } } - free(final_str); + dawn_free(final_str); } } diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index 49c09c4..c9c00cf 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -1,6 +1,7 @@ #include #include +#include "memory_utils.h" #include "dawn_iwinfo.h" #include "dawn_uci.h" #include "mac_utils.h" @@ -807,7 +808,7 @@ static client* client_array_unlink_entry(client** ref_bc, int unlink_only) } else { - free(entry); + dawn_free(entry); entry = NULL; } @@ -874,7 +875,7 @@ probe_entry* victim; victim = *i; *i = victim->next_probe; - free(victim); + dawn_free(victim); probe_entry_last--; } @@ -1117,7 +1118,7 @@ static __inline__ void ap_array_unlink_next(ap** i) { ap* entry = *i; *i = entry->next_ap; - free(entry); + dawn_free(entry); ap_entry_last--; } @@ -1203,10 +1204,10 @@ void insert_macs_from_file() { int tmp_int_mac[ETH_ALEN]; sscanf(line, MACSTR, STR2MAC(tmp_int_mac)); - struct mac_entry_s* new_mac = malloc(sizeof(struct mac_entry_s)); + struct mac_entry_s* new_mac = dawn_malloc(sizeof(struct mac_entry_s)); if (new_mac == NULL) { - printf("malloc of MAC struct failed!\n"); + printf("dawn_malloc of MAC struct failed!\n"); } else { @@ -1228,7 +1229,7 @@ void insert_macs_from_file() { fclose(fp); if (line) - free(line); + dawn_free(line); //exit(EXIT_SUCCESS); } @@ -1244,10 +1245,10 @@ struct mac_entry_s** i = mac_find_first_entry(mac); } else { - struct mac_entry_s* new_mac = malloc(sizeof(struct mac_entry_s)); + struct mac_entry_s* new_mac = dawn_malloc(sizeof(struct mac_entry_s)); if (new_mac == NULL) { - printf("malloc of MAC struct failed!\n"); + printf("dawn_malloc of MAC struct failed!\n"); } else { @@ -1316,7 +1317,7 @@ void denied_req_array_delete(auth_entry* entry) { if (*i == entry) { *i = entry->next_auth; denied_req_last--; - free(entry); + dawn_free(entry); break; } } @@ -1347,7 +1348,7 @@ void mac_array_delete(struct mac_entry_s* entry) { if (*i == entry) { *i = entry->next_mac; mac_set_last--; - free(entry); + dawn_free(entry); } } diff --git a/src/test/test_storage.c b/src/test/test_storage.c index d6a8413..3679a65 100644 --- a/src/test/test_storage.c +++ b/src/test/test_storage.c @@ -2,6 +2,7 @@ #include #include "dawn_iwinfo.h" +#include "memory_utils.h" #include "datastorage.h" #include "mac_utils.h" @@ -121,7 +122,7 @@ static int array_auto_helper(int action, int i0, int i1) ; // Empty statement to allow label before declaration if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) { - ap* ap0 = malloc(sizeof(struct ap_s)); + ap* ap0 = dawn_malloc(sizeof(struct ap_s)); ap0->bssid_addr = this_mac; insert_to_ap_array(ap0); @@ -133,7 +134,7 @@ static int array_auto_helper(int action, int i0, int i1) ; // Empty statement to allow label before declaration if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) { - client* client0 = malloc(sizeof(struct client_s)); + client* client0 = dawn_malloc(sizeof(struct client_s)); client0->bssid_addr = this_mac; client0->client_addr = this_mac; @@ -152,7 +153,7 @@ static int array_auto_helper(int action, int i0, int i1) probe_entry* probe0 = NULL; if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) { - probe0 = malloc(sizeof(probe_entry)); + probe0 = dawn_malloc(sizeof(probe_entry)); probe0->client_addr = this_mac; probe0->bssid_addr = this_mac; @@ -175,7 +176,7 @@ static int array_auto_helper(int action, int i0, int i1) ; // Empty statement to allow label before declaration if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_ADD) { - auth_entry* auth_entry0 = malloc(sizeof(struct auth_entry_s)); + auth_entry* auth_entry0 = dawn_malloc(sizeof(struct auth_entry_s)); auth_entry0->bssid_addr = this_mac; auth_entry0->client_addr = this_mac; @@ -306,9 +307,15 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) { args_required = 1; - char *leaky = malloc(10); + char* leaky = dawn_malloc(10); strcpy(leaky, "LEAKED"); // Force use of memory to avoid unused error } + else if (strcmp(*argv, "memaudit") == 0) + { + args_required = 1; + + dawn_memory_audit(); + } else if (strcmp(*argv, "probe_sort") == 0) { args_required = 2; @@ -580,7 +587,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) } else if (strcmp(*argv, "ap") == 0) { - ap *ap0 = malloc(sizeof(struct ap_s)); + ap *ap0 = dawn_malloc(sizeof(struct ap_s)); ap0->freq = 0; ap0->ht_support = 0; @@ -628,11 +635,11 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) if (ret == 0) insert_to_ap_array(ap0); else - free(ap0); + dawn_free(ap0); } else if (strcmp(*argv, "client") == 0) { - client *cl0 = malloc(sizeof(struct client_s)); + client *cl0 = dawn_malloc(sizeof(struct client_s)); //TODO: NULL test memset(cl0->signature, 0, SIGNATURE_LEN); @@ -748,8 +755,8 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) { if (harness_verbosity > 1) printf("probe: creating new entry...\n"); - // MUSTDO: Check all new malloc() returns - pr0 = malloc(sizeof(probe_entry)); + // MUSTDO: Check all new dawn_malloc() returns + pr0 = dawn_malloc(sizeof(probe_entry)); pr0->bssid_addr = bmac; pr0->client_addr = cmac; @@ -779,7 +786,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity) } else if (strcmp(*argv, "auth_entry") == 0) { - auth_entry *au0 = malloc(sizeof(struct auth_entry_s)); + auth_entry *au0 = dawn_malloc(sizeof(struct auth_entry_s)); memset(au0->bssid_addr.u8, 0, ETH_ALEN); memset(au0->client_addr.u8, 0, ETH_ALEN); @@ -1098,7 +1105,7 @@ int main(int argc, char* argv[]) if (line) { - free(line); + dawn_free(line); line = NULL; } } diff --git a/src/utils/dawn_iwinfo.c b/src/utils/dawn_iwinfo.c index 331b836..3ad3918 100644 --- a/src/utils/dawn_iwinfo.c +++ b/src/utils/dawn_iwinfo.c @@ -50,6 +50,7 @@ int compare_essid_iwinfo(struct dawn_mac bssid_addr, struct dawn_mac bssid_addr_ iw = iwinfo_backend(entry->d_name); + // TODO: Magic number static char buf_bssid[18] = {0}; if (iw->bssid(entry->d_name, buf_bssid)) snprintf(buf_bssid, sizeof(buf_bssid), "00:00:00:00:00:00"); diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index a44e8b7..8d9508f 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -2,6 +2,7 @@ #include #include +#include "memory_utils.h" #include "datastorage.h" #include "dawn_iwinfo.h" #include "dawn_uci.h" @@ -23,6 +24,7 @@ void uci_get_hostname(char* hostname) char path[]= "system.@system[0].hostname"; struct uci_ptr ptr; struct uci_context *c = uci_alloc_context(); + dawn_regmem(c); if(!c){ return; @@ -30,6 +32,7 @@ void uci_get_hostname(char* hostname) if ((uci_lookup_ptr(c, &ptr, path, true) != UCI_OK) || (ptr.o==NULL || ptr.o->v.string==NULL)){ uci_free_context(c); + dawn_unregmem(c); return; } @@ -46,6 +49,7 @@ void uci_get_hostname(char* hostname) } uci_free_context(c); + dawn_unregmem(c); } struct time_config_s uci_get_time_config() { @@ -197,6 +201,7 @@ int uci_init() { if (!ctx) { ctx = uci_alloc_context(); + dawn_regmem(ctx); uci_ctx = ctx; ctx->flags &= ~UCI_FLAG_STRICT; @@ -209,7 +214,11 @@ int uci_init() { } if (uci_load(ctx, "dawn", &uci_pkg)) + { + // TODO: Is this allocating memory? + dawn_regmem(uci_pkg); return -1; + } return 1; } @@ -217,9 +226,11 @@ int uci_init() { int uci_clear() { if (uci_pkg != NULL) { uci_unload(uci_ctx, uci_pkg); + dawn_unregmem(uci_pkg); } if (uci_ctx != NULL) { uci_free_context(uci_ctx); + dawn_unregmem(uci_ctx); } return 1; } @@ -232,6 +243,7 @@ int uci_set_network(char* uci_cmd) if (!ctx) { ctx = uci_alloc_context(); + dawn_regmem(ctx); uci_ctx = ctx; } diff --git a/src/utils/mac_utils.c b/src/utils/mac_utils.c index 5de95ad..b72b19a 100644 --- a/src/utils/mac_utils.c +++ b/src/utils/mac_utils.c @@ -50,6 +50,8 @@ void write_mac_to_file(char* path, struct dawn_mac addr) { FILE* f = fopen(path, "a"); if (f == NULL) { fprintf(stderr, "Error opening mac file!\n"); + + // TODO: Should this be an exit()? exit(1); } diff --git a/src/utils/memory_utils.c b/src/utils/memory_utils.c new file mode 100644 index 0000000..e06b6ca --- /dev/null +++ b/src/utils/memory_utils.c @@ -0,0 +1,172 @@ +#include +#include +#include + +#include "memory_utils.h" + +#define DAWN_MEM_FILENAME_LEN 20 +struct mem_list { + struct mem_list* next_mem; + int line; + char file[DAWN_MEM_FILENAME_LEN]; + char type; + size_t size; + void* ptr; +}; + +struct mem_list* mem_base = NULL; + +void* dawn_memory_alloc(enum dawn_memop type, char* file, int line, size_t nmemb, size_t size, void *ptr) +{ + void* ret = NULL; + + switch (type) + { + case DAWN_MALLOC: + ret = malloc(size); + break; + case DAWN_REALLOC: + dawn_memory_unregister(DAWN_REALLOC, file, line, ptr); + ret = realloc(ptr, size); + break; + case DAWN_CALLOC: + ret = calloc(nmemb, size); + size *= nmemb; // May not be correct allowing for padding but gives a sense of scale + break; + default: + break; + } + + if (ret != NULL) + dawn_memory_register(type, file, line, size, ret); + + return ret; +} + +void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t size, void* ptr) +{ + void* ret = NULL; + struct mem_list* this_log = NULL; + char type_c = '?'; + + // Ignore over enthusiastic effort to register a failed allocation + if (ptr == NULL) + return ret; + + switch (type) + { + case DAWN_MALLOC: + type_c = 'M'; + break; + case DAWN_REALLOC: + type_c = 'R'; + break; + case DAWN_CALLOC: + type_c = 'C'; + break; + case DAWN_MEMREG: + type_c = 'X'; + break; + default: + printf("Unexpected memory op tag!\n"); + break; + } + + // Insert to linked list with ascending memory reference + struct mem_list** ipos = &mem_base; + while (*ipos != NULL && (*ipos)->ptr < ptr) + ipos = &((*ipos)->next_mem); + + if (*ipos != NULL && (*ipos)->ptr == ptr) + { + printf("attempting to register memory already registered (%c@%s:%d)...\n", type_c, file, line); + } + else + { + this_log = malloc(sizeof(struct mem_list)); + + if (this_log == NULL) + { + printf("Oh the irony! malloc() failed in dawn_memory_register()!\n"); + } + else + { + this_log->next_mem = *ipos; + *ipos = this_log; + + // Just use filename - no path + file = strrchr(file, '/'); + + if (file != NULL) + strncpy(this_log->file, file + 1, DAWN_MEM_FILENAME_LEN); + else + strncpy(this_log->file, "?? UNKNOWN ??", DAWN_MEM_FILENAME_LEN); + + this_log->type = type_c; + this_log->line = line; + this_log->ptr = ptr; + this_log->size = size; + } + } + + return ret; +} + +void dawn_memory_unregister(enum dawn_memop type, char* file, int line, void* ptr) +{ + struct mem_list** mem = &mem_base; + char type_c = '?'; + + while (*mem != NULL && (*mem)->ptr <= ptr) + { + mem = &((*mem)->next_mem); + } + + switch (type) + { + case DAWN_FREE: + type_c = 'F'; + break; + case DAWN_MEMUNREG: + type_c = 'U'; + break; + case DAWN_REALLOC: + type_c = 'R'; + break; + default: + printf("Unexpected memory op tag!\n"); + break; + } + + if (*mem != NULL && (*mem)->ptr == ptr) + { + struct mem_list* tmp = *mem; + *mem = tmp->next_mem; + free(tmp); + } + else + { + printf("Releasing (%c) memory we hadn't registered (%s:%d)...\n", type_c, file, line); + } + + return; +} + +void dawn_memory_free(enum dawn_memop type, char* file, int line, void* ptr) +{ + dawn_memory_unregister(type, file, line, ptr); + + free(ptr); + + return; +} + +void dawn_memory_audit() +{ + printf("Currently recorded memory allocations...\n"); + for (struct mem_list* mem = mem_base; mem != NULL; mem = mem->next_mem) + { + printf("%c - %s@%d: %ld\n", mem->type, mem->file, mem->line, mem->size); + } + printf("[End of memory allocation list]\n"); +} diff --git a/src/utils/msghandler.c b/src/utils/msghandler.c index 5a70b5c..d83b28e 100644 --- a/src/utils/msghandler.c +++ b/src/utils/msghandler.c @@ -1,5 +1,6 @@ #include +#include "memory_utils.h" #include "dawn_uci.h" #include "datastorage.h" #include "ubus.h" @@ -146,10 +147,10 @@ int parse_to_hostapd_notify(struct blob_attr* msg, hostapd_notify_entry* notify_ probe_entry *parse_to_probe_req(struct blob_attr* msg) { struct blob_attr* tb[__PROB_MAX]; - probe_entry* prob_req = malloc(sizeof(probe_entry)); + probe_entry* prob_req = dawn_malloc(sizeof(probe_entry)); if (prob_req == NULL) { - fprintf(stderr, "malloc of probe_entry failed!\n"); + fprintf(stderr, "dawn_malloc of probe_entry failed!\n"); return NULL; } @@ -157,19 +158,19 @@ probe_entry *parse_to_probe_req(struct blob_attr* msg) { if (hwaddr_aton(blobmsg_data(tb[PROB_BSSID_ADDR]), prob_req->bssid_addr.u8)) { - free(prob_req); + dawn_free(prob_req); return NULL; } if (hwaddr_aton(blobmsg_data(tb[PROB_CLIENT_ADDR]), prob_req->client_addr.u8)) { - free(prob_req); + dawn_free(prob_req); return NULL; } if (hwaddr_aton(blobmsg_data(tb[PROB_TARGET_ADDR]), prob_req->target_addr.u8)) { - free(prob_req); + dawn_free(prob_req); return NULL; } @@ -286,7 +287,7 @@ int handle_network_msg(char* msg) { if (entry != insert_to_array(entry, false, false, false)) // use 802.11k values { // insert found an existing entry, rather than linking in our new one - free(entry); + dawn_free(entry); } } } @@ -358,7 +359,7 @@ dump_rrm_table(struct blob_attr* head, int len) //modify from examples/blobmsg-e static void dump_client(struct blob_attr** tb, struct dawn_mac client_addr, const char* bssid_addr, uint32_t freq, uint8_t ht_supported, uint8_t vht_supported) { - client *client_entry = malloc(sizeof(struct client_s)); + client *client_entry = dawn_malloc(sizeof(struct client_s)); if (client_entry == NULL) { // MUSTDO: Error handling? @@ -480,7 +481,7 @@ int parse_to_clients(struct blob_attr* msg, int do_kick, uint32_t id) { num_stations = dump_client_table(blobmsg_data(tb[CLIENT_TABLE]), blobmsg_data_len(tb[CLIENT_TABLE]), blobmsg_data(tb[CLIENT_TABLE_BSSID]), blobmsg_get_u32(tb[CLIENT_TABLE_FREQ]), blobmsg_get_u8(tb[CLIENT_TABLE_HT]), blobmsg_get_u8(tb[CLIENT_TABLE_VHT])); - ap *ap_entry = malloc(sizeof(struct ap_s)); + ap *ap_entry = dawn_malloc(sizeof(struct ap_s)); hwaddr_aton(blobmsg_data(tb[CLIENT_TABLE_BSSID]), ap_entry->bssid_addr.u8); ap_entry->freq = blobmsg_get_u32(tb[CLIENT_TABLE_FREQ]); diff --git a/src/utils/ubus.c b/src/utils/ubus.c index ad6ccd8..10b1868 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -1,6 +1,7 @@ #include #include +#include "memory_utils.h" #include "networksocket.h" #include "tcpsocket.h" #include "mac_utils.h" @@ -349,10 +350,10 @@ int parse_to_beacon_rep(struct blob_attr *msg) { { printf("Beacon: No Probe Entry Existing!\n"); - probe_entry* beacon_rep = malloc(sizeof(probe_entry)); + probe_entry* beacon_rep = dawn_malloc(sizeof(probe_entry)); if (beacon_rep == NULL) { - fprintf(stderr, "malloc of probe_entry failed!\n"); + fprintf(stderr, "dawn_malloc of probe_entry failed!\n"); return -1; } @@ -376,7 +377,7 @@ int parse_to_beacon_rep(struct blob_attr *msg) { { // insert found an existing entry, rather than linking in our new one ubus_send_probe_via_network(beacon_rep); - free(beacon_rep); + dawn_free(beacon_rep); } else ubus_send_probe_via_network(beacon_rep); @@ -389,7 +390,7 @@ int ret = WLAN_STATUS_SUCCESS; bool discard_entry = true; print_probe_array(); - auth_entry *auth_req = malloc(sizeof(struct auth_entry_s)); + auth_entry *auth_req = dawn_malloc(sizeof(struct auth_entry_s)); if (auth_req == NULL) return -1; @@ -426,7 +427,7 @@ bool discard_entry = true; } if (discard_entry) - free(auth_req); + dawn_free(auth_req); return ret; } @@ -436,7 +437,7 @@ int ret = WLAN_STATUS_SUCCESS; int discard_entry = true; print_probe_array(); - auth_entry* auth_req = malloc(sizeof(struct auth_entry_s)); + auth_entry* auth_req = dawn_malloc(sizeof(struct auth_entry_s)); if (auth_req == NULL) return -1; @@ -472,13 +473,13 @@ int discard_entry = true; } if (discard_entry) - free(auth_req); + dawn_free(auth_req); return ret; } static int handle_probe_req(struct blob_attr *msg) { - // MUSTDO: Untangle malloc() and linking of probe_entry + // MUSTDO: Untangle dawn_malloc() and linking of probe_entry probe_entry* probe_req = parse_to_probe_req(msg); if (probe_req != NULL) { @@ -487,7 +488,7 @@ static int handle_probe_req(struct blob_attr *msg) { { // insert found an existing entry, rather than linking in our new one ubus_send_probe_via_network(probe_req); - free(probe_req); + dawn_free(probe_req); } else ubus_send_probe_via_network(probe_req); @@ -499,7 +500,7 @@ static int handle_probe_req(struct blob_attr *msg) { } } - // TODO: Retrun for malloc() failure? + // TODO: Retrun for dawn_malloc() failure? return WLAN_STATUS_SUCCESS; } @@ -514,7 +515,7 @@ static int handle_beacon_rep(struct blob_attr *msg) { } -int send_blob_attr_via_network(struct blob_attr *msg, char *method) { +int send_blob_attr_via_network(struct blob_attr* msg, char* method) { if (!msg) { return -1; @@ -523,11 +524,13 @@ int send_blob_attr_via_network(struct blob_attr *msg, char *method) { char *data_str; char *str; data_str = blobmsg_format_json(msg, true); + dawn_regmem(data_str); blob_buf_init(&b_send_network, 0); blobmsg_add_string(&b_send_network, "method", method); blobmsg_add_string(&b_send_network, "data", data_str); str = blobmsg_format_json(b_send_network.head, true); + dawn_regmem(str); if (network_config.network_option == 2) { send_tcp(str); @@ -539,8 +542,8 @@ int send_blob_attr_via_network(struct blob_attr *msg, char *method) { } } - free(data_str); - free(str); + dawn_free(data_str); + dawn_free(str); return 0; } @@ -550,8 +553,9 @@ static int hostapd_notify(struct ubus_context *ctx, struct ubus_object *obj, struct blob_attr *msg) { char *str; str = blobmsg_format_json(msg, true); + dawn_regmem(str); printf("Method new: %s : %s\n", method, str); - free(str); + dawn_free(str); struct hostapd_sock_entry *entry; struct ubus_subscriber *subscriber; @@ -593,6 +597,7 @@ int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir) { return -1; } else { printf("Connected to ubus\n"); + dawn_regmem(ctx); } ubus_add_uloop(ctx); @@ -630,6 +635,7 @@ int dawn_init_ubus(const char *ubus_socket, const char *hostapd_dir) { close_socket(); ubus_free(ctx); + dawn_unregmem(ctx); uloop_done(); return 0; } @@ -641,6 +647,7 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ return; char *data_str = blobmsg_format_json(msg, 1); + dawn_regmem(data_str); blob_buf_init(&b_domain, 0); blobmsg_add_json_from_string(&b_domain, data_str); blobmsg_add_u32(&b_domain, "collision_domain", network_config.collision_domain); @@ -655,13 +662,13 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ if (entry == NULL) { fprintf(stderr, "Failed to find interface!\n"); - free(data_str); + dawn_free(data_str); return; } if (!entry->subscribed) { fprintf(stderr, "Interface %s is not subscribed!\n", entry->iface_name); - free(data_str); + dawn_free(data_str); return; } @@ -687,7 +694,7 @@ static void ubus_get_clients_cb(struct ubus_request *req, int type, struct blob_ print_client_array(); print_ap_array(); - free(data_str); + dawn_free(data_str); } static int ubus_get_clients() { @@ -1248,7 +1255,7 @@ bool subscriber_to_interface(const char *ifname) { struct hostapd_sock_entry *hostapd_entry; - hostapd_entry = calloc(1, sizeof(struct hostapd_sock_entry)); + hostapd_entry = dawn_calloc(1, sizeof(struct hostapd_sock_entry)); strcpy(hostapd_entry->iface_name, ifname); // add hostname