AST-2020-001 - res_pjsip: Return dialog locked and referenced

pjproject returns the dialog locked and with a reference. However,
in Asterisk the method that handles this decrements the reference
and removes the lock prior to returning. This makes it possible,
under some circumstances, for another thread to free said dialog
before the thread that created it attempts to use it again. Of
course when the thread that created it tries to use a freed dialog
a crash can occur.

This patch makes it so Asterisk now returns the newly created
dialog both locked, and with an added reference. This allows the
caller to de-reference, and unlock the dialog when it is safe to
do so.

In the case of a new SIP Invite the lock, and reference are now
held for the entirety of the new invite handling process.
Otherwise it's possible for the dialog, or its dependent objects,
like the transaction, to disappear. For example if there is a TCP
transport error.

ASTERISK-29057 #close

Change-Id: I5ef645a47829596f402cf383dc02c629c618969e
(cherry picked from commit 6baa4b53be)
This commit is contained in:
Kevin Harwell
2020-11-04 15:08:10 -06:00
committed by George Joseph
parent cd8f8b94f8
commit b82f880647
4 changed files with 226 additions and 26 deletions

View File

@@ -1477,7 +1477,7 @@ static struct sip_subscription_tree *create_subscription_tree(const struct ast_s
}
sub_tree->role = AST_SIP_NOTIFIER;
dlg = ast_sip_create_dialog_uas(endpoint, rdata, dlg_status);
dlg = ast_sip_create_dialog_uas_locked(endpoint, rdata, dlg_status);
if (!dlg) {
if (*dlg_status != PJ_EEXISTS) {
ast_log(LOG_WARNING, "Unable to create dialog for SIP subscription\n");
@@ -1498,8 +1498,16 @@ static struct sip_subscription_tree *create_subscription_tree(const struct ast_s
}
pjsip_evsub_create_uas(dlg, &pubsub_cb, rdata, 0, &sub_tree->evsub);
subscription_setup_dialog(sub_tree, dlg);
/*
* The evsub and subscription setup both add dialog refs, so the dialog ref that
* was added when the dialog was created (see ast_sip_create_dialog_uas_lock) can
* now be removed. The lock should no longer be needed so can be removed too.
*/
pjsip_dlg_dec_lock(dlg);
#ifdef HAVE_PJSIP_EVSUB_GRP_LOCK
pjsip_evsub_add_ref(sub_tree->evsub);
#endif