Summary:ASTERISK-21951: res_fax unsafely unlocks channel to perform an asynchronous goto to the 'fax' extension
Reporter:Matt Jordan (mjordan)Labels:
Date Opened:2013-06-21 22:02:27Date Closed:
Versions:12 11.4.0 13.18.4 Frequency of
Description:This bug affects Asterisk in 11, but is more prevalent in Asterisk 12.

When executing in a framehook, the channel *must* remain locked. Otherwise, the channel's list of framehooks can be changed out from under it, and the traversal of the framehooks becomes unsafe.

Unfortunately, in {{res_fax}}, there is at least one place where we have to unlock the channel - when we bounce to the {{fax}} extension. Note that we currently don't ref bump the channel prior to doing that either, which is probably wrong.

In 12, however, it actually will get worse - we can no longer access the bridged peer of the channel safely without first locking the bridge. This creates a locking inversion, as the bridge should be locked prior to locking the channel. Deadlock avoidance won't work here (which is what the bridge attempts to do), as the channel still shouldn't be unlocked.

This boils down to a problem that cannot be easily solved safely.

The good news is that it is highly unlikely for the framehook list to be modified while a channel is waiting for a fax to start.

A short term solution will be to ref bump the channel for the lifetime of these calls and unlock/lock the channel to prevent deadlocks. This is not terribly safe, but beats the current deadlocks.

A longer term solution is to replace the list of framehooks with an ao2_container. Iterators for ao2_containers version the objects in the container such that modifying the contents of the container does not remove or add ao2 objects in the iteration. This would allow unlocking the channel safely.