From 1b62781be08b73b2572be08ec3ac97068ba46b6f Mon Sep 17 00:00:00 2001 From: Alexei Gradinari <alex2grad@gmail.com> Date: Tue, 28 May 2019 16:35:17 -0400 Subject: [PATCH] res_fax: fix segfault on inactive "reserved" fax session The change #10017 "Handle fax gateway being started more than once" introdiced a bug which leads to segfault in res_fax_spandsp. The res_fax_spandsp module does not support reserving sessions, so fax_session_reserve returns a fax session with state AST_FAX_STATE_INACTIVE. The fax_gateway_start does not create a real fax session if the fax session is already present and the state is not AST_FAX_STATE_RESERVED. But the "reserved" session created for res_fax_spandsp has state AST_FAX_STATE_INACTIVE, so fax_gateway_start not starting. Then when fax_gateway_framehook is called and gateway T.38 state is NEGOTIATED the call of gateway->s->tech->write(gateway->s, f) leads to segfault, because session tech_pvt is not set, i.e. the tech session was not initialized/started. This patch adds check also on AST_FAX_STATE_INACTIVE to the "reserved" session created for res_fax_spandsp will start. This patch also adds extra check and log ERROR if tech_pvt is not set before call tech->write. ASTERISK-27981 #close Change-Id: Ife3e65e5f18c902db2ff0538fccf7d28f88fa803 --- res/res_fax.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/res/res_fax.c b/res/res_fax.c index 7338507bc9..647ec2ad15 100644 --- a/res/res_fax.c +++ b/res/res_fax.c @@ -1106,6 +1106,7 @@ static void destroy_session(void *session) s->details->caps &= ~AST_FAX_TECH_GATEWAY; } ao2_ref(s->details, -1); + s->details = NULL; } if (s->debug_info) { @@ -2915,7 +2916,8 @@ static int fax_gateway_start(struct fax_gateway *gateway, struct ast_fax_session int start_res; /* if the fax gateway is already started then do nothing */ - if (gateway->s && gateway->s->state != AST_FAX_STATE_RESERVED) { + if (gateway->s && + gateway->s->state != AST_FAX_STATE_RESERVED && gateway->s->state != AST_FAX_STATE_INACTIVE) { return 0; } @@ -3510,6 +3512,12 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct /* in gateway mode, gateway some packets */ if (gateway->t38_state == T38_STATE_NEGOTIATED) { struct ast_trans_pvt *readtrans; + + if (!gateway->s || !gateway->s->tech_pvt) { + ast_log(LOG_ERROR, "no FAX session on chan %s for T.38 gateway session, odd", ast_channel_name(chan)); + return f; + } + /* framehooks are called in __ast_read() before frame format * translation is done, so we need to translate here */ if ((f->frametype == AST_FRAME_VOICE) && (ast_format_cmp(f->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL) -- GitLab