From d0b1b3f63e7be1e47533f559d2968347b8797629 Mon Sep 17 00:00:00 2001 From: Grzegorz Sluja <grzegorz.sluja@iopsys.eu> Date: Tue, 5 Dec 2023 09:29:06 +0100 Subject: [PATCH] Fix the memory leak in blob_buf There were some places where blob_buf was allocated but never freed. Valgrind found it in the following backtrace: ==18922== 166,400 bytes in 650 blocks are definitely lost in loss record 35 of 38 ==18922== at 0x488FDE4: realloc (vg_replace_malloc.c:1649) ==18922== by 0x5E861A3: blob_buffer_grow (blob.c:26) ==18922== by 0x5E86213: blob_buf_grow (blob.c:63) ==18922== by 0x5E862CF: blob_add (blob.c:78) ==18922== by 0x5E8633F: blob_buf_init (blob.c:97) ==18922== by 0x5F5068F: ??? (in /usr/lib/asterisk/modules/chan_voicemngr.so) --- src/channels/chan_voicemngr.c | 56 ++++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/channels/chan_voicemngr.c b/src/channels/chan_voicemngr.c index 4526b99..7a5800c 100644 --- a/src/channels/chan_voicemngr.c +++ b/src/channels/chan_voicemngr.c @@ -426,12 +426,20 @@ static void endpt_get_codecs_cb(struct ubus_request *req, int type, struct blob_ static void voicemngr_codecs_init(void) { struct blob_buf bb; + int ret = 0; memset(&bb, 0, sizeof(bb)); - blob_buf_init(&bb, 0); + if(blob_buf_init(&bb, 0)) { + return; + } blobmsg_add_u8(&bb, "effective", 0); - ubus_invoke(get_shared_context(__FUNCTION__), endpt_id, "codecs", bb.head, + ret = ubus_invoke(get_shared_context(__FUNCTION__), endpt_id, "codecs", bb.head, endpt_get_codecs_cb, NULL, 2000); + + if (ret) + ast_log(LOG_ERROR, "Error invoking method: %s %d\n", "codecs", ret); + + blob_buf_free(&bb); } // codec data string to codec enum @@ -652,7 +660,9 @@ static void endpt_signal(int line, char *signal, char *state, char *data) { if (endpt_id) { memset(&bb, 0, sizeof(bb)); - blob_buf_init(&bb, 0); + if(blob_buf_init(&bb, 0)) { + return; + } blobmsg_add_u32(&bb, "line", line); blobmsg_add_string(&bb, "signal", signal); @@ -661,7 +671,10 @@ static void endpt_signal(int line, char *signal, char *state, char *data) { blobmsg_add_string(&bb, "data", data); req = calloc(1, sizeof(struct ubus_request)); - if (!req) return; + if (!req) { + blob_buf_free(&bb); + return; + } ast_verbose("thread %d: ubus call endpt signal\n", ast_get_tid()); res = ubus_invoke_async(get_shared_context(__FUNCTION__), endpt_id, "signal", bb.head, req); @@ -669,6 +682,7 @@ static void endpt_signal(int line, char *signal, char *state, char *data) { if(res != UBUS_STATUS_OK) { ast_log(LOG_ERROR, "Error invoking method: %s %d\n", "signal", res); free(req); + blob_buf_free(&bb); return; } @@ -676,6 +690,7 @@ static void endpt_signal(int line, char *signal, char *state, char *data) { req->complete_cb = ubus_call_complete; req->priv = NULL; ubus_complete_request_async(get_shared_context(__FUNCTION__), req); + blob_buf_free(&bb); } } @@ -717,7 +732,9 @@ static void endpt_connection_data(int line, int id, const char *action, const st if (endpt_id) { memset(&bb, 0, sizeof(bb)); - blob_buf_init(&bb, 0); + if(blob_buf_init(&bb, 0)) { + return; + } blobmsg_add_u32(&bb, "line", line); blobmsg_add_u32(&bb, "id", id); @@ -734,13 +751,17 @@ static void endpt_connection_data(int line, int id, const char *action, const st } req = calloc(1, sizeof(struct ubus_request)); - if (!req) return; + if (!req) { + blob_buf_free(&bb); + return; + } ast_verbose("thread %d: ubus call endpt connection\n", ast_get_tid()); res = ubus_invoke_async(get_shared_context(__FUNCTION__), endpt_id, "connection", bb.head, req); if(res != UBUS_STATUS_OK) { ast_log(LOG_ERROR, "Error invoking method: %s %d\n", "connection", res); free(req); + blob_buf_free(&bb); return; } @@ -748,6 +769,7 @@ static void endpt_connection_data(int line, int id, const char *action, const st req->complete_cb = ubus_call_complete; req->priv = NULL; ubus_complete_request_async(get_shared_context(__FUNCTION__), req); + blob_buf_free(&bb); } } @@ -4740,17 +4762,27 @@ static void endpt_get_count_cb(struct ubus_request *req, static int endpt_get_count(void) { struct blob_buf bb; + int ret = 0; endpt_id = get_ubus_endpt_id(0); if(!endpt_id) return -1; memset(&bb, 0, sizeof(bb)); - blob_buf_init(&bb, 0); + if(blob_buf_init(&bb, 0)) { + return -1; + } blobmsg_add_u8(&bb, "effective", 0); - return (ubus_invoke(get_shared_context(__FUNCTION__), endpt_id, "count", bb.head, - endpt_get_count_cb, NULL, 2000) == UBUS_STATUS_OK ? 0 : -1); + ret = ubus_invoke(get_shared_context(__FUNCTION__), endpt_id, "count", bb.head, + endpt_get_count_cb, NULL, 2000); + + if (ret) + ast_log(LOG_ERROR, "Error invoking method: %s %d\n", "count", ret); + + blob_buf_free(&bb); + + return ((ret == UBUS_STATUS_OK) ? 0 : -1); } static void ubus_call_answer_rtp_stats(struct ubus_request *req, int type, struct blob_attr *msg) { @@ -4912,7 +4944,9 @@ static int endpt_get_rtp_stats(int line) { } memset(&bb, 0, sizeof(bb)); - blob_buf_init(&bb, 0); + if(blob_buf_init(&bb, 0)) { + return -1; + } blobmsg_add_u32(&bb, "line", line); blobmsg_add_u8(&bb, "reset", 1); // always reset RTP stats after get them @@ -5025,9 +5059,11 @@ static int asterisk_call_status(struct ubus_context *ctx, struct ubus_object *ob blobmsg_close_table(&blob, table_stats); res = UBUS_STATUS_OK; } else { + blob_buf_free(&blob); return UBUS_STATUS_INVALID_ARGUMENT; } } else { + blob_buf_free(&blob); return UBUS_STATUS_INVALID_ARGUMENT; } -- GitLab