From 2a9b77bd0bb84d3b615141abd09c836dbe5b0189 Mon Sep 17 00:00:00 2001 From: redraincatching <99604494+redraincatching@users.noreply.github.com> Date: Tue, 9 Sep 2025 05:18:33 +0100 Subject: [PATCH] address possible null pointer dereferences (#1744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # addressing all remaining code scanning instances of warning C6011, null pointer dereference this pr aims to address more static code analyser warnings, specifically null pointer dereferences. the majority of changes are solely to quieten the analyser, as `malloc` and `calloc` are unlikely to fail, but this should at least lead to the code analysis being more readable and usable. where functions addressed had existing failure strategies, they were used, however some functions will now silently fail rather than attempting to dereference a null pointer. if there is a preferred solution in these cases, i will be happy to implement it. --- this is an extension of [this pull request](https://github.com/coturn/coturn/pull/1729) --- src/apps/common/apputils.c | 8 ++++-- src/apps/relay/dbdrivers/dbd_mongo.c | 5 ++++ src/apps/relay/http_server.c | 5 ++++ src/apps/relay/netengine.c | 4 +++ src/apps/relay/ns_ioalib_engine_impl.c | 37 +++++++++++++++++++++----- src/apps/relay/turn_admin_server.c | 9 +++++++ src/apps/relay/userdb.c | 4 +++ src/apps/uclient/startuclient.c | 5 ++++ src/apps/uclient/uclient.c | 4 +++ src/client/ns_turn_msg.c | 3 +++ src/server/ns_turn_maps.c | 12 +++++---- 11 files changed, 83 insertions(+), 13 deletions(-) diff --git a/src/apps/common/apputils.c b/src/apps/common/apputils.c index 6f824b1..dda312e 100644 --- a/src/apps/common/apputils.c +++ b/src/apps/common/apputils.c @@ -923,8 +923,12 @@ static char *_WTA(__in wchar_t *pszInBuf, __in int nInSize, __out char **pszOutB free(*pszOutBuf); return NULL; } else { - (*pszOutBuf)[*pnOutSize - 1] = '\0'; - return *pszOutBuf; + if (pszOutBuf != NULL) { + (*pszOutBuf)[*pnOutSize - 1] = '\0'; + return *pszOutBuf; + } else { + return NULL; + } } } diff --git a/src/apps/relay/dbdrivers/dbd_mongo.c b/src/apps/relay/dbdrivers/dbd_mongo.c index 0c80cc7..379c8da 100644 --- a/src/apps/relay/dbdrivers/dbd_mongo.c +++ b/src/apps/relay/dbdrivers/dbd_mongo.c @@ -98,6 +98,11 @@ static MONGO *get_mongodb_connection(void) { mydbconnection = (MONGO *)calloc(1, sizeof(MONGO)); + if (mydbconnection == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return NULL; + } + mydbconnection->uri = mongoc_uri_new(pud->userdb); if (!mydbconnection->uri) { diff --git a/src/apps/relay/http_server.c b/src/apps/relay/http_server.c index 4a25ff9..c0b71c6 100644 --- a/src/apps/relay/http_server.c +++ b/src/apps/relay/http_server.c @@ -220,6 +220,11 @@ struct http_request *parse_http_request(char *request) { ret = (struct http_request *)calloc(sizeof(struct http_request), 1); + if (ret == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return NULL; + } + if (strstr(request, "GET ") == request) { ret->rtype = HRT_GET; ret = parse_http_request_1(ret, request + 4, 0); diff --git a/src/apps/relay/netengine.c b/src/apps/relay/netengine.c index 06f8284..353012b 100644 --- a/src/apps/relay/netengine.c +++ b/src/apps/relay/netengine.c @@ -341,6 +341,10 @@ static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params) { update_ssl_ctx_cb_args_t *args = (update_ssl_ctx_cb_args_t *)malloc(sizeof(update_ssl_ctx_cb_args_t)); + if (args == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return; + } args->engine = e; args->params = params; args->next = NULL; diff --git a/src/apps/relay/ns_ioalib_engine_impl.c b/src/apps/relay/ns_ioalib_engine_impl.c index 85aa11c..772a3e2 100644 --- a/src/apps/relay/ns_ioalib_engine_impl.c +++ b/src/apps/relay/ns_ioalib_engine_impl.c @@ -331,6 +331,10 @@ static inline void add_elem_to_buffer_list(stun_buffer_list *bufs, stun_buffer_l static void add_buffer_to_buffer_list(stun_buffer_list *bufs, char *buf, size_t len) { if (bufs && buf && (bufs->tsz < MAX_SOCKET_BUFFER_BACKLOG)) { stun_buffer_list_elem *buf_elem = (stun_buffer_list_elem *)malloc(sizeof(stun_buffer_list_elem)); + if (buf_elem == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return; + } memcpy(buf_elem->buf.buf, buf, len); buf_elem->buf.len = len; buf_elem->buf.offset = 0; @@ -576,6 +580,11 @@ ioa_timer_handle set_ioa_timer(ioa_engine_handle e, int secs, int ms, ioa_timer_ if (e && cb && secs > 0) { timer_event *te = (timer_event *)malloc(sizeof(timer_event)); + if (te == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return NULL; + } + int flags = EV_TIMEOUT; if (persist) { flags |= EV_PERSIST; @@ -926,6 +935,11 @@ ioa_socket_handle create_unbound_relay_ioa_socket(ioa_engine_handle e, int famil ret = (ioa_socket *)calloc(sizeof(ioa_socket), 1); + if (ret == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return NULL; + } + ret->magic = SOCKET_MAGIC; ret->fd = fd; @@ -1018,8 +1032,9 @@ int create_relay_ioa_sockets(ioa_engine_handle e, ioa_socket_handle client_s, in port = turnipports_allocate_even(tp, &relay_addr, even_port, out_reservation_token); if (port >= 0 && even_port > 0) { - - IOA_CLOSE_SOCKET(*rtcp_s); + if (rtcp_s != NULL) { + IOA_CLOSE_SOCKET(*rtcp_s); + } *rtcp_s = create_unbound_relay_ioa_socket(e, relay_addr.ss.sa_family, UDP_SOCKET, RELAY_RTCP_SOCKET); if (*rtcp_s == NULL) { perror("socket"); @@ -1343,6 +1358,11 @@ ioa_socket_handle create_ioa_socket_from_fd(ioa_engine_handle e, ioa_socket_raw ret = (ioa_socket *)calloc(sizeof(ioa_socket), 1); + if (ret == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return NULL; + } + ret->magic = SOCKET_MAGIC; ret->fd = fd; @@ -3641,7 +3661,7 @@ void turn_report_allocation_set(void *a, turn_time_t lifetime, int refresh) { } } #if !defined(TURN_NO_HIREDIS) - { + if (e && ss) { char key[1024]; if (ss->realm_options.name[0]) { snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/status", ss->realm_options.name, @@ -3687,7 +3707,7 @@ void turn_report_allocation_delete(void *a, SOCKET_TYPE socket_type) { (unsigned long long)ss->id, (char *)ss->realm_options.name, (char *)ss->username); } #if !defined(TURN_NO_HIREDIS) - { + if (e) { char key[1024]; if (ss->realm_options.name[0]) { snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/status", ss->realm_options.name, @@ -3773,7 +3793,7 @@ void turn_report_session_usage(void *session, int force_invalid) { (unsigned long)(ss->peer_sent_packets), (unsigned long)(ss->peer_sent_bytes)); } #if !defined(TURN_NO_HIREDIS) - { + if (e) { char key[1024]; if (ss->realm_options.name[0]) { snprintf(key, sizeof(key), "turn/realm/%s/user/%s/allocation/%018llu/traffic", ss->realm_options.name, @@ -3867,8 +3887,13 @@ static void init_super_memory_region(super_memory_t *r) { if (r) { r->super_memory = (char **)malloc(sizeof(char *)); r->super_memory[0] = (char *)calloc(1, TURN_SM_SIZE); - r->sm_allocated = (size_t *)malloc(sizeof(size_t)); + + if (r->sm_allocated == NULL || r->super_memory == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return; + } + r->sm_allocated[0] = 0; r->sm_total_sz = TURN_SM_SIZE; diff --git a/src/apps/relay/turn_admin_server.c b/src/apps/relay/turn_admin_server.c index 2c75aea..8581912 100644 --- a/src/apps/relay/turn_admin_server.c +++ b/src/apps/relay/turn_admin_server.c @@ -1173,6 +1173,10 @@ static void cliserver_input_handler(struct evconnlistener *l, evutil_socket_t fd addr_debug_print(adminserver.verbose, (ioa_addr *)sa, "CLI connected to"); struct cli_session *clisession = (struct cli_session *)calloc(sizeof(struct cli_session), 1); + if (clisession == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return; + } clisession->rp = get_realm(NULL); @@ -1437,6 +1441,11 @@ void admin_server_receive_message(struct bufferevent *bev, void *ptr) { UNUSED_ARG(ptr); struct turn_session_info *tsi = (struct turn_session_info *)calloc(1, sizeof(struct turn_session_info)); + if (tsi == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return; + } + int n = 0; struct evbuffer *input = bufferevent_get_input(bev); diff --git a/src/apps/relay/userdb.c b/src/apps/relay/userdb.c index 510c282..7d30d7b 100644 --- a/src/apps/relay/userdb.c +++ b/src/apps/relay/userdb.c @@ -161,6 +161,10 @@ realm_params_t *get_realm(char *name) { } else { realm_params_t *ret = (realm_params_t *)malloc(sizeof(realm_params_t)); memcpy(ret, default_realm_params_ptr, sizeof(realm_params_t)); + if (ret == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: error allocating memory\n", __FUNCTION__); + return default_realm_params_ptr; + } STRCPY(ret->options.name, name); value = (ur_string_map_value_type)ret; ur_string_map_put(realms, key, value); diff --git a/src/apps/uclient/startuclient.c b/src/apps/uclient/startuclient.c index 9400e48..0f1b6d4 100644 --- a/src/apps/uclient/startuclient.c +++ b/src/apps/uclient/startuclient.c @@ -1593,6 +1593,11 @@ again: (app_tcp_conn_info **)realloc(elem->pinfo.tcp_conn, elem->pinfo.tcp_conn_number * sizeof(app_tcp_conn_info *)); elem->pinfo.tcp_conn[i] = (app_tcp_conn_info *)calloc(sizeof(app_tcp_conn_info), 1); + if (elem->pinfo.tcp_conn[i] == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: failure in call to calloc \n", __FUNCTION__); + return; + } + elem->pinfo.tcp_conn[i]->tcp_data_fd = clnet_fd; elem->pinfo.tcp_conn[i]->cid = cid; diff --git a/src/apps/uclient/uclient.c b/src/apps/uclient/uclient.c index a0133af..e47ef13 100644 --- a/src/apps/uclient/uclient.c +++ b/src/apps/uclient/uclient.c @@ -1409,6 +1409,10 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if } elems = (app_ur_session **)malloc(sizeof(app_ur_session) * ((mclient * 2) + 1) + sizeof(void *)); + if (elems == NULL) { + TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: failure in call to malloc !!!\n", __FUNCTION__); + return; + } __turn_getMSTime(); uint32_t stime = current_time; diff --git a/src/client/ns_turn_msg.c b/src/client/ns_turn_msg.c index d9e2ad8..a204353 100644 --- a/src/client/ns_turn_msg.c +++ b/src/client/ns_turn_msg.c @@ -181,6 +181,9 @@ bool stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, const size_t sz = ulen + 1 + rlen + 1 + plen + 1 + 10; const size_t strl = ulen + 1 + rlen + 1 + plen; uint8_t *str = (uint8_t *)malloc(sz + 1); + if (str == NULL) { + return false; + } strncpy((char *)str, (const char *)uname, sz); str[ulen] = ':'; diff --git a/src/server/ns_turn_maps.c b/src/server/ns_turn_maps.c index b9d3458..8423499 100644 --- a/src/server/ns_turn_maps.c +++ b/src/server/ns_turn_maps.c @@ -282,11 +282,13 @@ bool lm_map_put(lm_map *map, ur_map_key_type key, ur_map_value_type value) { a->extra_values = (ur_map_value_type **)realloc(a->extra_values, old_sz_mem + sizeof(ur_map_value_type *)); assert(a->extra_values); a->extra_values[old_sz] = (ur_map_value_type *)malloc(sizeof(ur_map_value_type)); - *(a->extra_values[old_sz]) = value; - - a->extra_sz += 1; - - return true; + if (a->extra_values[old_sz] != NULL) { + *(a->extra_values[old_sz]) = value; + a->extra_sz += 1; + return true; + } else { + return false; + } } bool lm_map_get(const lm_map *map, ur_map_key_type key, ur_map_value_type *value) {