summaryrefslogtreecommitdiff
path: root/toxcore/TCP_server.c
diff options
context:
space:
mode:
authorzugz (tox) <mbays+tox@sdf.org>2018-09-29 10:49:52 +0200
committerzugz (tox) <mbays+tox@sdf.org>2018-10-07 20:13:51 +0200
commit5beb00c93d3adb5c23149535624d27c67bc146ea (patch)
tree270dcde41751d421fae86f8f466038c212ed559d /toxcore/TCP_server.c
parentb2b96b1aa19ef2eb2816303e606a3f23550538dc (diff)
Fix memleak in tcp server by wiping priority queues on deletion
Diffstat (limited to 'toxcore/TCP_server.c')
-rw-r--r--toxcore/TCP_server.c99
1 files changed, 67 insertions, 32 deletions
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index 2b6878fe..23b95940 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -124,43 +124,74 @@ size_t tcp_server_listen_count(const TCP_Server *tcp_server)
124#endif 124#endif
125#endif 125#endif
126 126
127/* Set the size of the connection list to numfriends. 127/* Increase the size of the connection list
128 * 128 *
129 * return -1 if realloc fails. 129 * return -1 on failure
130 * return 0 if it succeeds. 130 * return 0 on success.
131 */ 131 */
132static int realloc_connection(TCP_Server *tcp_server, uint32_t num) 132static int alloc_new_connections(TCP_Server *tcp_server, uint32_t num)
133{ 133{
134 if (num == 0) { 134 const uint32_t new_size = tcp_server->size_accepted_connections + num;
135 free(tcp_server->accepted_connection_array);
136 tcp_server->accepted_connection_array = nullptr;
137 tcp_server->size_accepted_connections = 0;
138 return 0;
139 }
140 135
141 if (num == tcp_server->size_accepted_connections) { 136 if (new_size < tcp_server->size_accepted_connections) {
142 return 0; 137 return -1;
143 } 138 }
144 139
145 TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc( 140 TCP_Secure_Connection *new_connections = (TCP_Secure_Connection *)realloc(
146 tcp_server->accepted_connection_array, 141 tcp_server->accepted_connection_array,
147 num * sizeof(TCP_Secure_Connection)); 142 new_size * sizeof(TCP_Secure_Connection));
148 143
149 if (new_connections == nullptr) { 144 if (new_connections == nullptr) {
150 return -1; 145 return -1;
151 } 146 }
152 147
153 if (num > tcp_server->size_accepted_connections) { 148 const uint32_t old_size = tcp_server->size_accepted_connections;
154 uint32_t old_size = tcp_server->size_accepted_connections; 149 const uint32_t size_new_entries = num * sizeof(TCP_Secure_Connection);
155 uint32_t size_new_entries = (num - old_size) * sizeof(TCP_Secure_Connection); 150 memset(new_connections + old_size, 0, size_new_entries);
156 memset(new_connections + old_size, 0, size_new_entries);
157 }
158 151
159 tcp_server->accepted_connection_array = new_connections; 152 tcp_server->accepted_connection_array = new_connections;
160 tcp_server->size_accepted_connections = num; 153 tcp_server->size_accepted_connections = new_size;
161 return 0; 154 return 0;
162} 155}
163 156
157void wipe_priority_list(TCP_Priority_List *p)
158{
159 while (p) {
160 TCP_Priority_List *pp = p;
161 p = p->next;
162 free(pp);
163 }
164}
165
166static void wipe_secure_connection(TCP_Secure_Connection *con)
167{
168 if (con->status) {
169 wipe_priority_list(con->priority_queue_start);
170 crypto_memzero(con, sizeof(TCP_Secure_Connection));
171 }
172}
173
174static void move_secure_connection(TCP_Secure_Connection *con_new, TCP_Secure_Connection *con_old)
175{
176 memcpy(con_new, con_old, sizeof(TCP_Secure_Connection));
177 crypto_memzero(con_old, sizeof(TCP_Secure_Connection));
178}
179
180static void free_accepted_connection_array(TCP_Server *tcp_server)
181{
182 if (tcp_server->accepted_connection_array == nullptr) {
183 return;
184 }
185
186 for (uint32_t i = 0; i < tcp_server->size_accepted_connections; ++i) {
187 wipe_secure_connection(&tcp_server->accepted_connection_array[i]);
188 }
189
190 free(tcp_server->accepted_connection_array);
191 tcp_server->accepted_connection_array = nullptr;
192 tcp_server->size_accepted_connections = 0;
193}
194
164/* return index corresponding to connection with peer on success 195/* return index corresponding to connection with peer on success
165 * return -1 on failure. 196 * return -1 on failure.
166 */ 197 */
@@ -177,7 +208,7 @@ static int kill_accepted(TCP_Server *tcp_server, int index);
177 * return index on success 208 * return index on success
178 * return -1 on failure 209 * return -1 on failure
179 */ 210 */
180static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, const TCP_Secure_Connection *con) 211static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, TCP_Secure_Connection *con)
181{ 212{
182 int index = get_TCP_connection_index(tcp_server, con->public_key); 213 int index = get_TCP_connection_index(tcp_server, con->public_key);
183 214
@@ -187,7 +218,7 @@ static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, cons
187 } 218 }
188 219
189 if (tcp_server->size_accepted_connections == tcp_server->num_accepted_connections) { 220 if (tcp_server->size_accepted_connections == tcp_server->num_accepted_connections) {
190 if (realloc_connection(tcp_server, tcp_server->size_accepted_connections + 4) == -1) { 221 if (alloc_new_connections(tcp_server, 4) == -1) {
191 return -1; 222 return -1;
192 } 223 }
193 224
@@ -212,7 +243,8 @@ static int add_accepted(TCP_Server *tcp_server, const Mono_Time *mono_time, cons
212 return -1; 243 return -1;
213 } 244 }
214 245
215 memcpy(&tcp_server->accepted_connection_array[index], con, sizeof(TCP_Secure_Connection)); 246 move_secure_connection(&tcp_server->accepted_connection_array[index], con);
247
216 tcp_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED; 248 tcp_server->accepted_connection_array[index].status = TCP_STATUS_CONFIRMED;
217 ++tcp_server->num_accepted_connections; 249 ++tcp_server->num_accepted_connections;
218 tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter; 250 tcp_server->accepted_connection_array[index].identifier = ++tcp_server->counter;
@@ -241,11 +273,11 @@ static int del_accepted(TCP_Server *tcp_server, int index)
241 return -1; 273 return -1;
242 } 274 }
243 275
244 crypto_memzero(&tcp_server->accepted_connection_array[index], sizeof(TCP_Secure_Connection)); 276 wipe_secure_connection(&tcp_server->accepted_connection_array[index]);
245 --tcp_server->num_accepted_connections; 277 --tcp_server->num_accepted_connections;
246 278
247 if (tcp_server->num_accepted_connections == 0) { 279 if (tcp_server->num_accepted_connections == 0) {
248 realloc_connection(tcp_server, 0); 280 free_accepted_connection_array(tcp_server);
249 } 281 }
250 282
251 return 0; 283 return 0;
@@ -513,7 +545,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const
513static void kill_TCP_secure_connection(TCP_Secure_Connection *con) 545static void kill_TCP_secure_connection(TCP_Secure_Connection *con)
514{ 546{
515 kill_sock(con->sock); 547 kill_sock(con->sock);
516 crypto_memzero(con, sizeof(TCP_Secure_Connection)); 548 wipe_secure_connection(con);
517} 549}
518 550
519static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number); 551static int rm_connection_index(TCP_Server *tcp_server, TCP_Secure_Connection *con, uint8_t con_number);
@@ -965,7 +997,7 @@ static int confirm_TCP_connection(TCP_Server *tcp_server, const Mono_Time *mono_
965 return -1; 997 return -1;
966 } 998 }
967 999
968 crypto_memzero(con, sizeof(TCP_Secure_Connection)); 1000 wipe_secure_connection(con);
969 1001
970 if (handle_TCP_packet(tcp_server, index, data, length) == -1) { 1002 if (handle_TCP_packet(tcp_server, index, data, length) == -1) {
971 kill_accepted(tcp_server, index); 1003 kill_accepted(tcp_server, index);
@@ -1152,8 +1184,7 @@ static int do_incoming(TCP_Server *tcp_server, uint32_t i)
1152 kill_TCP_secure_connection(conn_new); 1184 kill_TCP_secure_connection(conn_new);
1153 } 1185 }
1154 1186
1155 memcpy(conn_new, conn_old, sizeof(TCP_Secure_Connection)); 1187 move_secure_connection(conn_new, conn_old);
1156 crypto_memzero(conn_old, sizeof(TCP_Secure_Connection));
1157 ++tcp_server->unconfirmed_connection_queue_index; 1188 ++tcp_server->unconfirmed_connection_queue_index;
1158 1189
1159 return index_new; 1190 return index_new;
@@ -1435,9 +1466,7 @@ void do_TCP_server(TCP_Server *tcp_server, Mono_Time *mono_time)
1435 1466
1436void kill_TCP_server(TCP_Server *tcp_server) 1467void kill_TCP_server(TCP_Server *tcp_server)
1437{ 1468{
1438 uint32_t i; 1469 for (uint32_t i = 0; i < tcp_server->num_listening_socks; ++i) {
1439
1440 for (i = 0; i < tcp_server->num_listening_socks; ++i) {
1441 kill_sock(tcp_server->socks_listening[i]); 1470 kill_sock(tcp_server->socks_listening[i]);
1442 } 1471 }
1443 1472
@@ -1451,7 +1480,13 @@ void kill_TCP_server(TCP_Server *tcp_server)
1451 close(tcp_server->efd); 1480 close(tcp_server->efd);
1452#endif 1481#endif
1453 1482
1483 for (uint32_t i = 0; i < MAX_INCOMING_CONNECTIONS; ++i) {
1484 wipe_secure_connection(&tcp_server->incoming_connection_queue[i]);
1485 wipe_secure_connection(&tcp_server->unconfirmed_connection_queue[i]);
1486 }
1487
1488 free_accepted_connection_array(tcp_server);
1489
1454 free(tcp_server->socks_listening); 1490 free(tcp_server->socks_listening);
1455 free(tcp_server->accepted_connection_array);
1456 free(tcp_server); 1491 free(tcp_server);
1457} 1492}