Commit a950dc420b for asterisk.org
commit a950dc420b7b6075150c400a0a9b7b7b150044b9
Author: Alexandre Fournier <afournier@wazo.io>
Date: Thu Jul 23 16:52:36 2026 -0400
func_channel: add NULL checks on channel tech for dummy channels
A dummy channel allocated with ast_dummy_channel_alloc() never gets a
channel technology, so ast_channel_tech() returns NULL for it.
func_channel_read() dereferences ast_channel_tech(chan)->type for
CHANNEL(channeltype) without checking the tech for NULL, and
func_channel_write_real() dereferences it the same way in its fallback
branch. Both crash with a SIGSEGV on a dummy channel.
This happens when CHANNEL(channeltype) is present in channelvars of
ari.conf and the variable is evaluated on a dummy channel, e.g. when
a voicemail is deposited for a mailbox that has an email address
configured.
Guard both dereferences. A dummy channel has no technology, so
CHANNEL(channeltype) now reads as an empty string and a write falls
through to the "Unknown or unavailable item requested" warning.
This is very similar to the issue fixed by
https://github.com/asterisk/asterisk/pull/1993
Resolves: #2150
AI disclaimer: Claude Opus 4.8 was used to find the cause of the crash
and to find a solution.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
diff --git a/funcs/func_channel.c b/funcs/func_channel.c
index 15ca38ff0d..739a4786ec 100644
--- a/funcs/func_channel.c
+++ b/funcs/func_channel.c
@@ -462,7 +462,8 @@ static int func_channel_read(struct ast_channel *chan, const char *function,
locked_copy_string(chan, buf,
ast_channel_hold_state(chan) == AST_CONTROL_HOLD ? "1" : "0", len);
} else if (!strcasecmp(data, "channeltype"))
- locked_copy_string(chan, buf, ast_channel_tech(chan)->type, len);
+ locked_copy_string(chan, buf,
+ ast_channel_tech(chan) ? ast_channel_tech(chan)->type : "", len);
else if (!strcasecmp(data, "accountcode"))
locked_copy_string(chan, buf, ast_channel_accountcode(chan), len);
else if (!strcasecmp(data, "checkhangup")) {
@@ -797,7 +798,8 @@ static int func_channel_write_real(struct ast_channel *chan, const char *functio
}
} else if (!strcasecmp(data, "tenantid")) {
ast_channel_tenantid_set(chan, value);
- } else if (!ast_channel_tech(chan)->func_channel_write
+ } else if (!ast_channel_tech(chan)
+ || !ast_channel_tech(chan)->func_channel_write
|| ast_channel_tech(chan)->func_channel_write(chan, function, data, value)) {
ast_log(LOG_WARNING, "Unknown or unavailable item requested: '%s'\n",
data);