Author: rmudgett
Date: Tue Feb 17 09:31:46 2015
New Revision: 431898

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=431898
Log:
res_pjsip_refer: Fix crash from a REFER and BYE collision.

Analyzing a one-off crash on a busy system showed that processing a REFER
request had a NULL session channel pointer.  The only way I can think of
that could cause this is if an outgoing BYE transaction overlapped the
incoming REFER transaction in a collision.  Asterisk sends a BYE while the
phone sends a REFER to complete an attended transfer.

* Made check the session channel pointer before processing an incoming
REFER request in res_pjsip_refer.

* Fixed similar crash potential for res_pjsip supplement incoming request
processing for res_pjsip_sdp_rtp INFO, res_pjsip_caller_id INVITE/UPDATE,
res_pjsip_messaging MESSAGE, and res_pjsip_send_to_voicemail REFER
messages.

* Made res_pjsip_messaging respond to a message body too large with a 413
instead of ignoring it.

ASTERISK-24700 #close
Reported by: Zane Conkle

Review: https://reviewboard.asterisk.org/r/4417/

Modified:
    branches/13/res/res_pjsip_caller_id.c
    branches/13/res/res_pjsip_messaging.c
    branches/13/res/res_pjsip_refer.c
    branches/13/res/res_pjsip_sdp_rtp.c
    branches/13/res/res_pjsip_send_to_voicemail.c

Modified: branches/13/res/res_pjsip_caller_id.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_caller_id.c?view=diff&rev=431898&r1=431897&r2=431898
==============================================================================
--- branches/13/res/res_pjsip_caller_id.c (original)
+++ branches/13/res/res_pjsip_caller_id.c Tue Feb 17 09:31:46 2015
@@ -361,7 +361,7 @@
                if (!session->endpoint->id.self.number.valid) {
                        set_id_from_from(rdata, &session->id);
                }
-       } else {
+       } else if (session->channel) {
                /* Reinvite. Check for changes to the ID and queue a connected 
line
                 * update if necessary
                 */

Modified: branches/13/res/res_pjsip_messaging.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_messaging.c?view=diff&rev=431898&r1=431897&r2=431898
==============================================================================
--- branches/13/res/res_pjsip_messaging.c (original)
+++ branches/13/res/res_pjsip_messaging.c Tue Feb 17 09:31:46 2015
@@ -681,9 +681,13 @@
        char buf[MAX_BODY_SIZE];
        enum pjsip_status_code code;
        struct ast_frame f;
-
        pjsip_dialog *dlg = session->inv_session->dlg;
        pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
+
+       if (!session->channel) {
+               send_response(rdata, PJSIP_SC_NOT_FOUND, dlg, tsx);
+               return 0;
+       }
 
        if ((code = check_content_type(rdata)) != PJSIP_SC_OK) {
                send_response(rdata, code, dlg, tsx);
@@ -692,6 +696,7 @@
 
        if (print_body(rdata, buf, sizeof(buf)-1) < 1) {
                /* invalid body size */
+               send_response(rdata, PJSIP_SC_REQUEST_ENTITY_TOO_LARGE, dlg, 
tsx);
                return 0;
        }
 

Modified: branches/13/res/res_pjsip_refer.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_refer.c?view=diff&rev=431898&r1=431897&r2=431898
==============================================================================
--- branches/13/res/res_pjsip_refer.c (original)
+++ branches/13/res/res_pjsip_refer.c Tue Feb 17 09:31:46 2015
@@ -418,7 +418,7 @@
        struct refer_attended *attended = obj;
 
        ao2_cleanup(attended->transferer);
-       ast_channel_unref(attended->transferer_chan);
+       ast_channel_cleanup(attended->transferer_chan);
        ao2_cleanup(attended->transferer_second);
        ao2_cleanup(attended->progress);
 }
@@ -674,7 +674,7 @@
 
                return 200;
        } else {
-               const char *context = (session->channel ? 
pbx_builtin_getvar_helper(session->channel, "TRANSFER_CONTEXT") : "");
+               const char *context = 
pbx_builtin_getvar_helper(session->channel, "TRANSFER_CONTEXT");
                struct refer_blind refer = { 0, };
 
                if (ast_strlen_zero(context)) {
@@ -718,10 +718,6 @@
        char exten[AST_MAX_EXTENSION];
        struct refer_blind refer = { 0, };
 
-       if (!session->channel) {
-               return 404;
-       }
-
        /* If no explicit transfer context has been provided use their 
configured context */
        context = pbx_builtin_getvar_helper(session->channel, 
"TRANSFER_CONTEXT");
        if (ast_strlen_zero(context)) {
@@ -893,6 +889,14 @@
        static const pj_str_t str_refer_to = { "Refer-To", 8 };
        static const pj_str_t str_replaces = { "Replaces", 8 };
 
+       if (!session->channel) {
+               /* No channel to refer.  Likely because the call was just hung 
up. */
+               pjsip_dlg_respond(session->inv_session->dlg, rdata, 404, NULL, 
NULL, NULL);
+               ast_debug(3, "Received a REFER on a session with no channel 
from endpoint '%s'.\n",
+                       ast_sorcery_object_get_id(session->endpoint));
+               return 0;
+       }
+
        if (!session->endpoint->allowtransfer) {
                pjsip_dlg_respond(session->inv_session->dlg, rdata, 603, NULL, 
NULL, NULL);
                ast_log(LOG_WARNING, "Endpoint %s transfer attempt blocked due 
to configuration\n",

Modified: branches/13/res/res_pjsip_sdp_rtp.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_sdp_rtp.c?view=diff&rev=431898&r1=431897&r2=431898
==============================================================================
--- branches/13/res/res_pjsip_sdp_rtp.c (original)
+++ branches/13/res/res_pjsip_sdp_rtp.c Tue Feb 17 09:31:46 2015
@@ -1268,14 +1268,17 @@
 
 static int video_info_incoming_request(struct ast_sip_session *session, struct 
pjsip_rx_data *rdata)
 {
-       struct pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
+       struct pjsip_transaction *tsx;
        pjsip_tx_data *tdata;
 
-       if (!ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type,
-                                    "application",
-                                    "media_control+xml")) {
+       if (!session->channel
+               || 
!ast_sip_is_content_type(&rdata->msg_info.msg->body->content_type,
+                       "application",
+                       "media_control+xml")) {
                return 0;
        }
+
+       tsx = pjsip_rdata_get_tsx(rdata);
 
        ast_queue_control(session->channel, AST_CONTROL_VIDUPDATE);
 

Modified: branches/13/res/res_pjsip_send_to_voicemail.c
URL: 
http://svnview.digium.com/svn/asterisk/branches/13/res/res_pjsip_send_to_voicemail.c?view=diff&rev=431898&r1=431897&r2=431898
==============================================================================
--- branches/13/res/res_pjsip_send_to_voicemail.c (original)
+++ branches/13/res/res_pjsip_send_to_voicemail.c Tue Feb 17 09:31:46 2015
@@ -119,13 +119,17 @@
 
 static int handle_incoming_request(struct ast_sip_session *session, struct 
pjsip_rx_data *rdata)
 {
-
        struct ast_datastore *sip_session_datastore;
        struct ast_channel *other_party;
-
-       int has_feature = has_call_feature(rdata);
-       int has_reason = has_diversion_reason(rdata);
-
+       int has_feature;
+       int has_reason;
+
+       if (!session->channel) {
+               return 0;
+       }
+
+       has_feature = has_call_feature(rdata);
+       has_reason = has_diversion_reason(rdata);
        if (!has_feature && !has_reason) {
                /* If we don't have a call feature or diversion reason or if
                   it's not a feature this module is related to then there


-- 
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to