[asterisk-bugs] [JIRA] (ASTERISK-19550) Segfault in ast_readaudio_callback
Sean Bright (JIRA)
noreply at issues.asterisk.org
Wed Aug 11 12:15:33 CDT 2021
[ https://issues.asterisk.org/jira/browse/ASTERISK-19550?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sean Bright updated ASTERISK-19550:
-----------------------------------
Description:
Issue believed to occur on all versions. Raised here after email from Mark Michelson on -dev mailing list
Cause:
- SIP Refer (attended transfer) a caller into a Queue while the position announce is playing.
- The crash happens more easily on a fast multi-core server.
Under-the-hood:
The Queue position announce is being played using ast_readaudio_callback, which is called with an ast_filestream*, usually every 20ms.
In the meantime, The SIP Refer sets up a masquerade from within a separate thread. If that masquerade is picked-up by ast_read() or ast_waitfor_nandfs(), then all is happy, BUT, the ast_readaudio_callback() function uses ast_write, which can also trigger the ast_do_masquerade().
Depending on thread scheduling, the call to ast_do_masquerade can cause the stream's channel to be freed, or sometimes just marked as a ZOMBIE, but either way, the ast_filestream is usually closed using ast_closestream(), setting it's ao2 refcount to zero, destroying it, and allowing the memory to be re-used.
At this point execution passes back from the ast_write() to ast_readaudio_callback() where it tries to use the freed ast_filestream, which in my testing, generally points at garbage data, and if it survives that experience, it tries to access the freed channel instead.
was:
Issue believed to occur on all versions. Raised here after email from Mark Michelson on -dev mailing list
Cause:
- SIP Refer (attended transfer) a caller into a Queue while the
position announce is playing.
- The crash happens more easily on a fast multi-core server.
Under-the-hood:
The Queue position announce is being played using
ast_readaudio_callback, which is called with an ast_filestream*,
usually every 20ms.
In the meantime, The SIP Refer sets up a masquerade from within a
separate thread. If that masquerade is picked-up by ast_read() or
ast_waitfor_nandfs(), then all is happy, BUT, the
ast_readaudio_callback() function uses ast_write, which can also
trigger the ast_do_masquerade().
Depending on thread scheduling, the call to ast_do_masquerade can
cause the stream's channel to be freed, or sometimes just marked as a
ZOMBIE, but either way, the ast_filestream is usually closed using
ast_closestream(), setting it's ao2 refcount to zero, destroying it,
and allowing the memory to be re-used.
At this point execution passes back from the ast_write() to
ast_readaudio_callback() where it tries to use the freed
ast_filestream, which in my testing, generally points at garbage data,
and if it survives that experience, it tries to access the freed
channel instead.
> Segfault in ast_readaudio_callback
> ----------------------------------
>
> Key: ASTERISK-19550
> URL: https://issues.asterisk.org/jira/browse/ASTERISK-19550
> Project: Asterisk
> Issue Type: Bug
> Security Level: None
> Components: Core/FileFormatInterface
> Affects Versions: 1.4.43, 1.6.2.22, 1.8.10.0, 1.8.22.0, 10.2.0, 10.12.2, 11.4.0, 13.18.4
> Environment: Easier to reproduce in Intel multi-core servers.
> Reporter: Steve Davies
> Severity: Major
> Attachments: readaudio_callback_workaround
>
>
> Issue believed to occur on all versions. Raised here after email from Mark Michelson on -dev mailing list
> Cause:
> - SIP Refer (attended transfer) a caller into a Queue while the position announce is playing.
> - The crash happens more easily on a fast multi-core server.
> Under-the-hood:
> The Queue position announce is being played using ast_readaudio_callback, which is called with an ast_filestream*, usually every 20ms.
> In the meantime, The SIP Refer sets up a masquerade from within a separate thread. If that masquerade is picked-up by ast_read() or ast_waitfor_nandfs(), then all is happy, BUT, the ast_readaudio_callback() function uses ast_write, which can also trigger the ast_do_masquerade().
> Depending on thread scheduling, the call to ast_do_masquerade can cause the stream's channel to be freed, or sometimes just marked as a ZOMBIE, but either way, the ast_filestream is usually closed using ast_closestream(), setting it's ao2 refcount to zero, destroying it, and allowing the memory to be re-used.
> At this point execution passes back from the ast_write() to ast_readaudio_callback() where it tries to use the freed ast_filestream, which in my testing, generally points at garbage data, and if it survives that experience, it tries to access the freed channel instead.
--
This message was sent by Atlassian JIRA
(v6.2#6252)
More information about the asterisk-bugs
mailing list