]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_fax: Don't start a gateway if either channel is hung up
authorGeorge Joseph <gjoseph@digium.com>
Wed, 3 Jun 2020 16:23:31 +0000 (10:23 -0600)
committerGeorge Joseph <gjoseph@digium.com>
Wed, 10 Jun 2020 18:59:42 +0000 (13:59 -0500)
When fax_gateway_framehook is called and a gateway hasn't already
been started, the framehook gets the t38 state for both the current
channel and the peer.  That call trickles down to the channel
driver which determines the state.  If either channel is hung up
(or in the process of being hung up), the channel driver's tech_pvt
is going to be NULL which, in the case of chan_pjsip, will cause a
segfault.

* Added a hangup check for both the channel and peer channel
  before starting a fax gateway.

* Added a check for NULL tech_pvt to chan_pjsip_queryoption
  so we don't attempt to reference a tech_pvt that's already
  gone.

ASTERISK-28923
Reported by: Yury Kirsanov

Change-Id: I4e10e63b667bbb68c1c8623f977488f5d807897c

channels/chan_pjsip.c
res/res_fax.c

index 79e7c6e131471c67fa9719aadbc5bbf6d13f8457..74392c419a3d90fcd8ab6422c2eee82c4af70ad0 100644 (file)
@@ -1116,14 +1116,17 @@ static int chan_pjsip_devicestate(const char *data)
 static int chan_pjsip_queryoption(struct ast_channel *ast, int option, void *data, int *datalen)
 {
        struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(ast);
-       struct ast_sip_session *session = channel->session;
        int res = -1;
        enum ast_t38_state state = T38_STATE_UNAVAILABLE;
 
+       if (!channel) {
+               return -1;
+       }
+
        switch (option) {
        case AST_OPTION_T38_STATE:
-               if (session->endpoint->media.t38.enabled) {
-                       switch (session->t38state) {
+               if (channel->session->endpoint->media.t38.enabled) {
+                       switch (channel->session->t38state) {
                        case T38_LOCAL_REINVITE:
                        case T38_PEER_REINVITE:
                                state = T38_STATE_NEGOTIATING;
index 3f506d4718b405c9b3572321498e3c08604ca709..645508900a782e81b1a60db315223469a66db697 100644 (file)
@@ -3442,6 +3442,15 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
        if (!gateway->bridged) {
                enum ast_t38_state state_chan;
                enum ast_t38_state state_peer;
+               int chan_is_hungup;
+               int peer_is_hungup;
+
+               chan_is_hungup = ast_check_hangup(chan);
+               peer_is_hungup = ast_check_hangup(peer);
+               /* Don't start a gateway if either channel is hung up */
+               if (chan_is_hungup || peer_is_hungup) {
+                       return f;
+               }
 
                ast_channel_unlock(chan);
                state_chan = ast_channel_get_t38_state(chan);