Просмотр исходного кода

address possible null pointer dereferences (#1744)

# 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)
redraincatching 3 месяцев назад
Родитель
Сommit
2a9b77bd0b

+ 6 - 2
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;
+    }
   }
 }
 

+ 5 - 0
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) {

+ 5 - 0
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);

+ 4 - 0
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;

+ 31 - 6
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;

+ 9 - 0
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);
 

+ 4 - 0
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);

+ 5 - 0
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;
 

+ 4 - 0
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;

+ 3 - 0
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] = ':';

+ 7 - 5
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) {