mncc: Fix use after free on mncc socket disconnection

When the MNCC socket breaks down we would release all callds but when
there is no remote call the call would be released before

	if (call->remote)
		...

is being executed leading to a use after free. Fix it by copying the
legs first and assuming the call will be gone after that.

==3618== Invalid read of size 4
==3618==    at 0x804A18A: app_mncc_disconnected (app.c:49)
==3618==    by 0x804B52D: close_connection (mncc.c:255)
==3618==    by 0x804BCFA: mncc_rtp_send.constprop.13 (mncc.c:145)
==3618==    by 0x804CC86: check_setup (mncc.c:435)
==3618==    by 0x804CC86: mncc_data (mncc.c:795)
==3618==    by 0x42FCF94: osmo_fd_disp_fds (select.c:167)
==3618==    by 0x804D1F2: evpoll (evpoll.c:92)
==3618==    by 0x4205053: ??? (in /lib/i386-linux-gnu/libglib-2.0.so.0.4200.1)
==3618==    by 0x4205478: g_main_loop_run (in /lib/i386-linux-gnu/libglib-2.0.so.0.4200.1)
==3618==    by 0x8049AA6: main (main.c:171)
==3618==  Address 0x47f3258 is 64 bytes inside a block of size 76 free'd
==3618==    at 0x402A3A8: free (vg_replace_malloc.c:473)
==3618==    by 0x42E7FD1: ??? (in /usr/lib/i386-linux-gnu/libtalloc.so.2.1.5)
==3618==    by 0x804A3FD: call_leg_release (call.c:87)
==3618==    by 0x804A186: app_mncc_disconnected (app.c:48)
==3618==    by 0x804B52D: close_connection (mncc.c:255)
==3618==    by 0x804BCFA: mncc_rtp_send.constprop.13 (mncc.c:145)
==3618==    by 0x804CC86: check_setup (mncc.c:435)
==3618==    by 0x804CC86: mncc_data (mncc.c:795)
==3618==    by 0x42FCF94: osmo_fd_disp_fds (select.c:167)
==3618==    by 0x804D1F2: evpoll (evpoll.c:92)
==3618==    by 0x4205053: ??? (in /lib/i386-linux-gnu/libglib-2.0.so.0.4200.1)
==3618==    by 0x4205478: g_main_loop_run (in /lib/i386-linux-gnu/libglib-2.0.so.0.4200.1)
==3618==    by 0x8049AA6: main (main.c:171)
==3618==

Change-Id: I1889013ed315f896e4295358f6daf76ce523dc2a
changes/73/1973/2
Holger Hans Peter Freyther 6 years ago committed by Holger Freyther
parent 068f547954
commit 49880ddf74
  1. 17
      src/app.c

@ -29,6 +29,7 @@ void app_mncc_disconnected(struct mncc_connection *conn)
struct call *call, *tmp;
llist_for_each_entry_safe(call, tmp, &g_call_list, entry) {
struct call_leg *initial, *remote;
int has_mncc = 0;
if (call->initial && call->initial->type == CALL_TYPE_MNCC)
@ -40,14 +41,20 @@ void app_mncc_disconnected(struct mncc_connection *conn)
continue;
/*
* this call has a MNCC component and we will release it.
* this call has a MNCC component and we will release it now.
* There might be no remote so on the release of the initial
* leg the call might be gone. We may not touch call beyond
* that point.
*/
LOGP(DAPP, LOGL_NOTICE,
"Going to release call(%u) due MNCC.\n", call->id);
if (call->initial)
call->initial->release_call(call->initial);
if (call->remote)
call->remote->release_call(call->remote);
initial = call->initial;
remote = call->remote;
call = NULL;
if (initial)
initial->release_call(initial);
if (remote)
remote->release_call(remote);
}
}

Loading…
Cancel
Save