From f77db9c3ebbbfcf051b0a76157ba6f4ce6cfd89f Mon Sep 17 00:00:00 2001 From: George Joseph Date: Wed, 3 Jun 2020 10:23:31 -0600 Subject: [PATCH] res_fax: Don't start a gateway if either channel is hung up If a channel is hung up when the fax_gateway_framehook is called and a gateway hasn't already been started, a segfault will occur when the framehook tries to get the t38 state. * Added a check of hangup cause for both the channel and peer channel before starting a fax gateway. * Added a check for NULL channel tech to chan_pjsip_queryoption so we don't attempt to reference a channel tech that's already gone. ASTERISK-28923 Reported by: Yury Kirsanov Change-Id: I4e10e63b667bbb68c1c8623f977488f5d807897c --- channels/chan_pjsip.c | 9 ++++++--- res/res_fax.c | 13 +++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index c8b6fe7d4b..692151a93c 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -1238,14 +1238,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; diff --git a/res/res_fax.c b/res/res_fax.c index ebb2b46266..a319934e96 100644 --- a/res/res_fax.c +++ b/res/res_fax.c @@ -3442,6 +3442,19 @@ 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 hangupcause_chan; + int hangupcause_peer; + + + ast_channel_unlock(chan); + ast_channel_lock_both(chan, peer); + hangupcause_chan = ast_channel_hangupcause(chan); + hangupcause_peer = ast_channel_hangupcause(peer); + ast_channel_unlock(peer); + /* Don't start a gateway if either channel is hung up */ + if (hangupcause_chan > 0 || hangupcause_peer > 0) { + return f; + } ast_channel_unlock(chan); state_chan = ast_channel_get_t38_state(chan); -- 2.26.2