summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2014-11-20 14:55:45 +0000
committerJoshua Colp <jcolp@digium.com>2014-11-20 14:55:45 +0000
commite7f16827cb7c1664a3e34621e4638c1d86bfe274 (patch)
treee8936e37cb4e6f5106a721a1aff3d9a8ce8c6977
parentaeb5f34ecc8f51ed4f6032d4e152d37382076173 (diff)
AST-2014-016: Fix crash when receiving an in-dialog INVITE with Replaces in res_pjsip_refer.
The implementation of INVITE with Replaces in res_pjsip_refer did not expect them to occur in-dialog. As a result it would incorrectly attempt to hang up a channel it thought was under its control. In reality the channel would be under the control of another thread. When the other thread accessed the channel it would be accessing freed memory and could crash. This change makes res_pjsip_refer not act on an in-dialog INVITE with Replaces. ASTERISK-24528 #close Reported by: Joshua Colp ........ Merged revisions 428304 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@428305 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--res/res_pjsip_refer.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c
index 2d932f38e..99d43fd2f 100644
--- a/res/res_pjsip_refer.c
+++ b/res/res_pjsip_refer.c
@@ -785,6 +785,12 @@ static int refer_incoming_invite_request(struct ast_sip_session *session, struct
other_session = ast_sip_dialog_get_session(other_dlg);
pjsip_dlg_dec_lock(other_dlg);
+ /* Don't accept an in-dialog INVITE with Replaces as it does not make much sense */
+ if (session->inv_session->dlg->state == PJSIP_DIALOG_STATE_ESTABLISHED) {
+ response = 488;
+ goto end;
+ }
+
if (!other_session) {
response = 481;
ast_debug(3, "INVITE with Replaces received on channel '%s' from endpoint '%s', but requested session does not exist\n",
@@ -831,14 +837,20 @@ static int refer_incoming_invite_request(struct ast_sip_session *session, struct
end:
if (response) {
- ast_debug(3, "INVITE with Replaces failed on channel '%s', sending response of '%d'\n",
- ast_channel_name(session->channel), response);
- session->defer_terminate = 1;
- ast_hangup(session->channel);
- session->channel = NULL;
-
- if (pjsip_inv_end_session(session->inv_session, response, NULL, &packet) == PJ_SUCCESS) {
- ast_sip_session_send_response(session, packet);
+ if (session->inv_session->dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED) {
+ ast_debug(3, "INVITE with Replaces failed on channel '%s', sending response of '%d'\n",
+ ast_channel_name(session->channel), response);
+ session->defer_terminate = 1;
+ ast_hangup(session->channel);
+ session->channel = NULL;
+
+ if (pjsip_inv_end_session(session->inv_session, response, NULL, &packet) == PJ_SUCCESS) {
+ ast_sip_session_send_response(session, packet);
+ }
+ } else {
+ ast_debug(3, "INVITE with Replaces in-dialog on channel '%s', hanging up\n",
+ ast_channel_name(session->channel));
+ ast_queue_hangup(session->channel);
}
}