Re: patch: add reference counter to pjsip_inv_session to avoid race condition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Ming,

The dialog lock is not sufficient.
Look at function inv_set_state in pjsip/src/pjsip-ua/sip_inv.c
starting with
    if (inv->state == PJSIP_INV_STATE_DISCONNECTED &&
       prev_state != PJSIP_INV_STATE_DISCONNECTED)
    {

there isn't any dialog lock and immediately
destroying any data associated with pjsip_inv_session.

Look at function inv_on_state_incoming in pjsip/src/pjsip-ua/sip_inv.c
===
     case PJSIP_TSX_STATE_TERMINATED:
             /*.
             * This happens on transport error (e.g. failed to send
             * response)
             */
            inv_set_cause(inv, tsx->status_code, &tsx->status_text);
            inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
===
there isn't any dialog lock

The scenario:
Transport TLS
The incoming INVITE received, pjsip called an on_rx_request.
An application pushed the INVITE session's data to a task queue on the on_rx_request.
The application popped the task and started processing INVITE session on different thread.
The TCP/TLS connection has been disconnected (transport error),
as result PJSIP_TSX_STATE_TERMINATED.
The pjsip called inv_set_state with state PJSIP_INV_STATE_DISCONNECTED.
The pjsip called on_tsx_state_changed.
The application received on_tsx_state_changed, but on different thread then
this INVITE session was being processed.
The pjsip destroyed the INVITE session while application was still processing this session.

Attached the stack trace of the application thread which processed
the INVITE session.

Wednesday, August 24, 2016, 11:49:50 PM, you wrote:
> Thanks for the report and the patch. Is dialog lock not sufficient for
> this purpose? If not, can you please elaborate more, perhaps with a
> sample scenario (and a brief stack trace, if necessary)?

> FYI, we might have a similar problem in ticket #1902
> (https://trac.pjsip.org/repos/ticket/1902).

> Best regards,
> Ming

> On Tue, Aug 23, 2016 at 12:11 AM, Alexei Gradinari <alex2grad@xxxxxxxxx> wrote:
>> Hello,
>>
>> When a transport error occured on an INVITE session
>> the pjproject calls on_tsx_state_changed with new
>> state PJSIP_INV_STATE_DISCONNECTED and immediately
>> destroys the INVITE session.
>> At the same time this INVITE session could being
>> processed on another thread.
>> This thread could use the session's memory pools which
>> were already freed, so we get segfault.
>>
>> This patch adds a reference counter and new functions:
>> pjsip_inv_session_add_ref and pjsip_inv_session_dec_ref.
>> The INVITE session is destroyed only when the reference
>> counter has reached zero.
>>
>> To avoid race condition an application should call
>> pjsip_inv_session_add_ref/pjsip_inv_session_dec_ref.
#0  0x00007fcd39d65a9e in pj_pool_alloc_from_block () from /usr/lib64/libpj.so.2
#1  0x00007fcd39d65c35 in pj_pool_alloc () from /usr/lib64/libpj.so.2
#2  0x00007fcd3a5e5c8b in pjmedia_sdp_attr_to_rtpmap () from /usr/lib64/libpjmedia.so.2
#3  0x00007fcd147ebee4 in get_codecs (session=0x7fcd88097438, session=0x7fcd88097438, session_media=0x7fcd881b8be8, 
    codecs=0x7fcd04fd0580, stream=0x7fcd88056b88) at res_pjsip_sdp_rtp.c:246
#4  set_caps (session=session@entry=0x7fcd88097438, session_media=session_media@entry=0x7fcd881b8be8, 
    stream=stream@entry=0x7fcd88056b88) at res_pjsip_sdp_rtp.c:325
#5  0x00007fcd147ed7f2 in negotiate_incoming_sdp_stream (session=0x7fcd88097438, session_media=0x7fcd881b8be8, sdp=0x7fcd4c19c878, 
    stream=0x7fcd88056b88) at res_pjsip_sdp_rtp.c:917
#6  0x00007fcd392d624c in handle_incoming_sdp (session=0x7fcd88097438, sdp=0x7fcd4c19c878) at res_pjsip_session.c:266
#7  0x00007fcd392d9131 in new_invite (data=0x7fcd8802f5d8) at res_pjsip_session.c:2117
#8  0x00000000005ba2b8 in ast_taskprocessor_execute (tps=tps@entry=0x3ba2af8) at taskprocessor.c:967
#9  0x00000000005c1ac8 in execute_tasks (data=0x3ba2af8) at threadpool.c:1322
#10 0x00000000005ba2b8 in ast_taskprocessor_execute (tps=0x258d638) at taskprocessor.c:967
#11 0x00000000005c1ebc in threadpool_execute (pool=0x258c088) at threadpool.c:351
#12 worker_active (worker=0x7fcd2801a568) at threadpool.c:1105
#13 worker_start (arg=arg@entry=0x7fcd2801a568) at threadpool.c:1024
#14 0x00000000005cc5d9 in dummy_start (data=<optimized out>) at utils.c:1235
#15 0x00007fcda0421ce2 in start_thread () from /lib64/libpthread.so.0
#16 0x00007fcd9f9b28cd in clone () from /lib64/libc.so.6
_______________________________________________
Visit our blog: http://blog.pjsip.org

pjsip mailing list
pjsip@xxxxxxxxxxxxxxx
http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org

[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux