From 41f3a7da4d0ef47ba0b959f019cda3c05b3b8c1c Mon Sep 17 00:00:00 2001 From: George Joseph <gjoseph@digium.com> Date: Wed, 3 Jun 2020 10:23:31 -0600 Subject: [PATCH] res_fax: Don't start a gateway if either channel is hung up 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 | 9 ++++++--- res/res_fax.c | 9 +++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c index 99ef6440da..45918acfe2 100644 --- a/channels/chan_pjsip.c +++ b/channels/chan_pjsip.c @@ -1232,14 +1232,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 b895c57ad6..190ba1b850 100644 --- a/res/res_fax.c +++ b/res/res_fax.c @@ -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); -- GitLab