mirror of
https://github.com/asterisk/asterisk.git
synced 2026-06-23 08:49:21 -07:00
channel: Prevent crash during DTMF emulation when no timing module is loaded
Description: When Asterisk is running without a timing module, attempting to process DTMF triggers a segmentation fault. This occurs because the system attempts to access a null timing file descriptor when setting up the DTMF emulation timer. This fix ensures that the system checks for a valid timing source before attempting to start the DTMF emulation timer. If no timing module is present, it logs a warning and skips the emulation instead of crashing the process. Changes: - Modified main/channel.c to add a safety check within the __ast_read function. - Implemented a graceful return path when no timing source is available - Added a LOG_WARNING to inform the administrator that DTMF emulation was skipped due to missing timing modules. Testing: - Disabled all timing_ modules in modules.conf and confirmed with 'timing test'. - Reproduced the crash by modifying the dialplan with: exten => 707,1,NoOp(Starting DTMF - No Timing Mode) same => n,Answer() same => n,Background(demo-congrats) same => n,WaitExten(10) same => n,Hangup() And calling 707 followed by 1 - Verified that with the fix applied, the system logs "No timing module loaded; skipping DTMF timer" and continues dialplan execution without crashing. - Confirmed stability during concurrent media sessions and DTMF input. Fixes: #566
This commit is contained in:
committed by
github-actions[bot]
parent
5656a5851b
commit
7b8339fb52
+33
-7
@@ -2893,7 +2893,12 @@ void ast_deactivate_generator(struct ast_channel *chan)
|
||||
deactivate_generator_nolock(chan);
|
||||
if (should_trigger_dtmf_emulating(chan)) {
|
||||
/* if in the middle of dtmf emulation keep 50 tick per sec timer on rolling */
|
||||
ast_timer_set_rate(ast_channel_timer(chan), 50);
|
||||
struct ast_timer *timer = ast_channel_timer(chan);
|
||||
if (timer) {
|
||||
ast_timer_set_rate(timer, 50);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "No timing module loaded, DTMF length may be inaccurate\n");
|
||||
}
|
||||
}
|
||||
ast_channel_unlock(chan);
|
||||
}
|
||||
@@ -3183,6 +3188,7 @@ int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(co
|
||||
{
|
||||
int res;
|
||||
unsigned int real_rate = rate, max_rate;
|
||||
struct ast_timer *timer = ast_channel_timer(c);
|
||||
|
||||
ast_channel_lock(c);
|
||||
|
||||
@@ -3196,13 +3202,13 @@ int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int (*func)(co
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
if (rate && rate > (max_rate = ast_timer_get_max_rate(ast_channel_timer(c)))) {
|
||||
if (rate && rate > (max_rate = ast_timer_get_max_rate(timer))) {
|
||||
real_rate = max_rate;
|
||||
}
|
||||
|
||||
ast_debug(3, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
|
||||
|
||||
res = ast_timer_set_rate(ast_channel_timer(c), real_rate);
|
||||
res = ast_timer_set_rate(timer, real_rate);
|
||||
|
||||
if (ast_channel_timingdata(c) && ast_test_flag(ast_channel_flags(c), AST_FLAG_TIMINGDATA_IS_AO2_OBJ)) {
|
||||
ao2_ref(ast_channel_timingdata(c), -1);
|
||||
@@ -3912,7 +3918,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
|
||||
* timer events to generate null frames.
|
||||
*/
|
||||
if (!ast_channel_generator(chan)) {
|
||||
ast_timer_set_rate(ast_channel_timer(chan), 50);
|
||||
struct ast_timer *timer = ast_channel_timer(chan);
|
||||
if (timer) {
|
||||
ast_timer_set_rate(timer, 50);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "No timing module loaded, DTMF length may be inaccurate\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ast_channel_audiohooks(chan)) {
|
||||
@@ -3962,7 +3973,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
|
||||
* timer events to generate null frames.
|
||||
*/
|
||||
if (!ast_channel_generator(chan)) {
|
||||
ast_timer_set_rate(ast_channel_timer(chan), 50);
|
||||
struct ast_timer *timer = ast_channel_timer(chan);
|
||||
if (timer) {
|
||||
ast_timer_set_rate(timer, 50);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "No timing module loaded, DTMF length may be inaccurate\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass.integer, ast_channel_name(chan));
|
||||
@@ -3977,7 +3993,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
|
||||
* timer events to generate null frames.
|
||||
*/
|
||||
if (!ast_channel_generator(chan)) {
|
||||
ast_timer_set_rate(ast_channel_timer(chan), 50);
|
||||
struct ast_timer *timer = ast_channel_timer(chan);
|
||||
if (timer) {
|
||||
ast_timer_set_rate(timer, 50);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "No timing module loaded, DTMF length may be inaccurate\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ast_channel_audiohooks(chan)) {
|
||||
@@ -4039,7 +4060,12 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
|
||||
* timer events to generate null frames.
|
||||
*/
|
||||
if (!ast_channel_generator(chan)) {
|
||||
ast_timer_set_rate(ast_channel_timer(chan), 50);
|
||||
struct ast_timer *timer = ast_channel_timer(chan);
|
||||
if (timer) {
|
||||
ast_timer_set_rate(timer, 50);
|
||||
} else {
|
||||
ast_log(LOG_WARNING, "No timing module loaded, DTMF length may be inaccurate\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user