From deafdb7f4b474701289a8086fbf44a05e19feca6 Mon Sep 17 00:00:00 2001 From: Razvan Crainea Date: Thu, 9 May 2019 18:22:32 +0300 Subject: [PATCH] tm: prevent concurrency between different cleanup This fixes a problem that was happening when having a transaction that wasn't fully updated, for example in a Push Nofitication scenario where no t_relay() was made, multiple messages may have reached the do_t_cleanup() function in parallel, both updating the transaction. Reported by 46Labs --- modules/tm/tm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/tm/tm.c b/modules/tm/tm.c index 39647206bc0..1231e165244 100644 --- a/modules/tm/tm.c +++ b/modules/tm/tm.c @@ -712,10 +712,15 @@ static int do_t_cleanup( struct sip_msg *foo, void *bar) reset_e2eack_t(); - if ( (t=get_t())!=NULL && t!=T_UNDEFINED && /* we have a transaction */ - /* with an UAS request not yet updated from script msg */ - t->uas.request && (t->uas.request->msg_flags & FL_SHM_UPDATED)==0 ) - update_cloned_msg_from_msg( t->uas.request, foo); + if ( (t=get_t())!=NULL && t!=T_UNDEFINED && t->uas.request) { + /* check the UAS request not yet updated from script msg */ + LOCK_REPLIES(t); + if (t->uas.request->msg_flags & FL_SHM_UPDATED) + LM_DBG("transaction %p already updated! Skipping update!\n", t); + else + update_cloned_msg_from_msg( t->uas.request, foo); + UNLOCK_REPLIES(t); + } return t_unref(foo) == 0 ? SCB_DROP_MSG : SCB_RUN_ALL; }