mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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:
committed by
George Joseph
parent
cd8f8b94f8
commit
b82f880647
@@ -4056,7 +4056,11 @@ static int uas_use_sips_contact(pjsip_rx_data *rdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
|
||||
typedef pj_status_t (*create_dlg_uac)(pjsip_user_agent *ua, pjsip_rx_data *rdata,
|
||||
const pj_str_t *contact, pjsip_dialog **p_dlg);
|
||||
|
||||
static pjsip_dialog *create_dialog_uas(const struct ast_sip_endpoint *endpoint,
|
||||
pjsip_rx_data *rdata, pj_status_t *status, create_dlg_uac create_fun)
|
||||
{
|
||||
pjsip_dialog *dlg;
|
||||
pj_str_t contact;
|
||||
@@ -4091,11 +4095,7 @@ pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint,
|
||||
(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? ";transport=" : "",
|
||||
(type != PJSIP_TRANSPORT_UDP && type != PJSIP_TRANSPORT_UDP6) ? pjsip_transport_get_type_name(type) : "");
|
||||
|
||||
#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
|
||||
*status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(), rdata, &contact, &dlg);
|
||||
#else
|
||||
*status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg);
|
||||
#endif
|
||||
*status = create_fun(pjsip_ua_instance(), rdata, &contact, &dlg);
|
||||
if (*status != PJ_SUCCESS) {
|
||||
char err[PJ_ERR_MSG_SIZE];
|
||||
|
||||
@@ -4112,13 +4112,47 @@ pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint,
|
||||
|
||||
ast_sip_tpselector_unref(&selector);
|
||||
|
||||
#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
|
||||
pjsip_dlg_dec_lock(dlg);
|
||||
#endif
|
||||
|
||||
return dlg;
|
||||
}
|
||||
|
||||
pjsip_dialog *ast_sip_create_dialog_uas(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
|
||||
{
|
||||
#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
|
||||
pjsip_dialog *dlg;
|
||||
|
||||
dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
|
||||
if (dlg) {
|
||||
pjsip_dlg_dec_lock(dlg);
|
||||
}
|
||||
|
||||
return dlg;
|
||||
#else
|
||||
return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
|
||||
#endif
|
||||
}
|
||||
|
||||
pjsip_dialog *ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint,
|
||||
pjsip_rx_data *rdata, pj_status_t *status)
|
||||
{
|
||||
#ifdef HAVE_PJSIP_DLG_CREATE_UAS_AND_INC_LOCK
|
||||
return create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas_and_inc_lock);
|
||||
#else
|
||||
/*
|
||||
* This is put here in order to be compatible with older versions of pjproject.
|
||||
* Best we can do in this case is immediately lock after getting the dialog.
|
||||
* However, that does leave a "gap" between creating and locking.
|
||||
*/
|
||||
pjsip_dialog *dlg;
|
||||
|
||||
dlg = create_dialog_uas(endpoint, rdata, status, pjsip_dlg_create_uas);
|
||||
if (dlg) {
|
||||
pjsip_dlg_inc_lock(dlg);
|
||||
}
|
||||
|
||||
return dlg;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ast_sip_create_rdata_with_contact(pjsip_rx_data *rdata, char *packet, const char *src_name, int src_port,
|
||||
char *transport_type, const char *local_name, int local_port, const char *contact)
|
||||
{
|
||||
|
Reference in New Issue
Block a user