mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 20:20:07 +00:00
bridge_channel_write_frame: Check for NULL channel
There is a possibility, when bridge_channel_write_frame() is called, that the bridge_channel->chan will be NULL. The first thing bridge_channel_write_frame() does though is call ast_channel_is_multistream() which had no check for a NULL channel and therefore caused a segfault. Since it's still possible for bridge_channel_write_frame() to write the frame to the other channels in the bridge, we don't want to bail before we call ast_channel_is_multistream() but we can just skip the multi-channel stuff. So... bridge_channel_write_frame() only calls ast_channel_is_multistream() if bridge_channel->chan is not NULL. As a safety measure, ast_channel_is_multistream() now returns false if the supplied channel is NULL. ASTERISK-29379 Reported-by: Vyrva Igor Reported-by: Ross Beer Change-Id: Idfe62dbea8c69813ecfd58e113a6620dc42352ce
This commit is contained in:
committed by
Friendly Automation
parent
84115fe657
commit
a4a63db253
@@ -657,8 +657,13 @@ static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel,
|
|||||||
|
|
||||||
ast_bridge_channel_lock_bridge(bridge_channel);
|
ast_bridge_channel_lock_bridge(bridge_channel);
|
||||||
|
|
||||||
/* Map the frame to the bridge. */
|
/*
|
||||||
if (ast_channel_is_multistream(bridge_channel->chan)) {
|
* Map the frame to the bridge.
|
||||||
|
* We need to lock the bridge_channel to make sure that bridge_channel->chan
|
||||||
|
* isn't NULL and keep it locked while we do multistream processing.
|
||||||
|
*/
|
||||||
|
ast_bridge_channel_lock(bridge_channel);
|
||||||
|
if (bridge_channel->chan && ast_channel_is_multistream(bridge_channel->chan)) {
|
||||||
unmapped_stream_num = frame->stream_num;
|
unmapped_stream_num = frame->stream_num;
|
||||||
switch (frame->frametype) {
|
switch (frame->frametype) {
|
||||||
case AST_FRAME_VOICE:
|
case AST_FRAME_VOICE:
|
||||||
@@ -672,12 +677,10 @@ static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel,
|
|||||||
frame->stream_num = -1;
|
frame->stream_num = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ast_bridge_channel_lock(bridge_channel);
|
|
||||||
if (frame->stream_num < (int)AST_VECTOR_SIZE(&bridge_channel->stream_map.to_bridge)) {
|
if (frame->stream_num < (int)AST_VECTOR_SIZE(&bridge_channel->stream_map.to_bridge)) {
|
||||||
frame->stream_num = AST_VECTOR_GET(
|
frame->stream_num = AST_VECTOR_GET(
|
||||||
&bridge_channel->stream_map.to_bridge, frame->stream_num);
|
&bridge_channel->stream_map.to_bridge, frame->stream_num);
|
||||||
if (0 <= frame->stream_num) {
|
if (0 <= frame->stream_num) {
|
||||||
ast_bridge_channel_unlock(bridge_channel);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,6 +706,7 @@ static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel,
|
|||||||
unmapped_stream_num = -1;
|
unmapped_stream_num = -1;
|
||||||
frame->stream_num = -1;
|
frame->stream_num = -1;
|
||||||
}
|
}
|
||||||
|
ast_bridge_channel_unlock(bridge_channel);
|
||||||
|
|
||||||
deferred = bridge_channel->bridge->technology->write(bridge_channel->bridge, bridge_channel, frame);
|
deferred = bridge_channel->bridge->technology->write(bridge_channel->bridge, bridge_channel, frame);
|
||||||
if (deferred) {
|
if (deferred) {
|
||||||
|
@@ -1587,5 +1587,5 @@ void ast_channel_internal_swap_stream_topology(struct ast_channel *chan1,
|
|||||||
|
|
||||||
int ast_channel_is_multistream(struct ast_channel *chan)
|
int ast_channel_is_multistream(struct ast_channel *chan)
|
||||||
{
|
{
|
||||||
return (chan->tech && chan->tech->read_stream && chan->tech->write_stream);
|
return (chan && chan->tech && chan->tech->read_stream && chan->tech->write_stream);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user