Commit 71a8a9e2 authored by Fabrice Bellet's avatar Fabrice Bellet Committed by Olivier Crête

component: Fix use-after-free and resolve regression

conn_check_prune_socket() on nsocket must be called before removing the
candidate with this socket inside the loop, to prevent the
use-after-free reported initially in issue #73.

But commit 541801d4 introduced a regression during discovery when an udp
turn over tcp socket is immediately closed by a HUP condition for
example. In this case, discovery_prune_socket() is never called, because
we don't have a candidate with this socket inside the loop. So the
nsocket is freed by the final nice_component_detach_socket() but is
still used by the discovery timer callback.

This commit moves the discovery_prune_socket() and
conn_check_prune_socket() actions before the loop instead of after, or
inside.

Closes #73
parent cceaffeb
...@@ -172,6 +172,10 @@ nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp, ...@@ -172,6 +172,10 @@ nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp,
stream = agent_find_stream (agent, cmp->stream_id); stream = agent_find_stream (agent, cmp->stream_id);
discovery_prune_socket (agent, nsocket);
if (stream)
conn_check_prune_socket (agent, stream, cmp, nsocket);
for (i = cmp->local_candidates; i;) { for (i = cmp->local_candidates; i;) {
NiceCandidate *candidate = i->data; NiceCandidate *candidate = i->data;
GSList *next = i->next; GSList *next = i->next;
...@@ -188,14 +192,10 @@ nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp, ...@@ -188,14 +192,10 @@ nice_component_remove_socket (NiceAgent *agent, NiceComponent *cmp,
} }
refresh_prune_candidate (agent, candidate); refresh_prune_candidate (agent, candidate);
discovery_prune_socket (agent, candidate->sockptr); if (candidate->sockptr != nsocket && stream) {
if (stream) { discovery_prune_socket (agent, candidate->sockptr);
conn_check_prune_socket (agent, stream, cmp, conn_check_prune_socket (agent, stream, cmp,
candidate->sockptr); candidate->sockptr);
}
/* Keep nsocket alive since it's used in the loop. */
if (candidate->sockptr != nsocket) {
nice_component_detach_socket (cmp, candidate->sockptr); nice_component_detach_socket (cmp, candidate->sockptr);
} }
agent_remove_local_candidate (agent, candidate); agent_remove_local_candidate (agent, candidate);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment