]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2021-002: Remote crash possible when negotiating T.38
authorKevin Harwell <kharwell@sangoma.com>
Mon, 1 Feb 2021 21:24:25 +0000 (15:24 -0600)
committerGeorge Joseph <gjoseph@digium.com>
Thu, 18 Feb 2021 16:38:03 +0000 (10:38 -0600)
When an endpoint requests to re-negotiate for fax and the incoming
re-invite is received prior to Asterisk sending out the 200 OK for
the initial invite the re-invite gets delayed. When Asterisk does
finally send the re-inivite the SDP includes streams for both audio
and T.38.

This happens because when the pending topology and active topologies
differ (pending stream is not in the active) in the delayed scenario
the pending stream is appended to the active topology. However, in
the fax case the pending stream should replace the active.

This patch makes it so when a delay occurs during fax negotiation,
to or from, the audio stream is replaced by the T.38 stream, or vice
versa instead of being appended.

Further when Asterisk sent the re-invite with both audio and T.38,
and the endpoint responded with a declined T.38 stream then Asterisk
would crash when attempting to change the T.38 state.

This patch also puts in a check that ensures the media state has a
valid fax session (associated udptl object) before changing the
T.38 state internally.

ASTERISK-29203 #close

Change-Id: I407f4fa58651255b6a9030d34fd6578cf65ccf09

res/res_pjsip_session.c
res/res_pjsip_t38.c

index d841aca04eb103a297b308e3729a13774725cd2e..48741f8bb50cbcb9aec3c7140d9d37f3dccd4455 100644 (file)
@@ -2283,7 +2283,14 @@ static int sip_session_refresh(struct ast_sip_session *session,
                                        ast_sip_session_get_name(session));
                        }
 
-                       if (active_media_state && active_media_state->topology) {
+                       /*
+                        * Attempt to resolve only if objects are available, and it's not
+                        * switching to or from an image type.
+                        */
+                       if (active_media_state && active_media_state->topology &&
+                               (!active_media_state->default_session[AST_MEDIA_TYPE_IMAGE] ==
+                                !pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE])) {
+
                                struct ast_sip_session_media_state *new_pending_state;
                                /*
                                 * We need to check if the passed in active and pending states are equal
index 9c9569b4f233a1217e5677c86e9c8b6019bd16a0..63abce5abf836a27b9db9e766e5374798f9e313c 100644 (file)
@@ -320,6 +320,15 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
                int index;
 
                session_media = session->active_media_state->default_session[AST_MEDIA_TYPE_IMAGE];
+
+               /*
+                * If there is a session_media object, but no udptl object available
+                * then it's assumed the stream was declined.
+                */
+               if (!session_media->udptl) {
+                       session_media = NULL;
+               }
+
                if (!session_media) {
                        ast_log(LOG_WARNING, "Received %d response to T.38 re-invite on '%s' but no active session media\n",
                                        status.code, session->channel ? ast_channel_name(session->channel) : "unknown channel");