[asterisk-dev] Another IAX2 problem with the latest security fix ...

Tim Panton thp at westhawk.co.uk
Fri May 30 03:19:30 CDT 2008

On 29 May 2008, at 16:47, Russell Bryant wrote:

> Greetings,
> After the last IAX2 security fix was made to chan_iax2, we hit some  
> unforeseen
> problems.  One of which was the impact on performance, which was  
> quickly
> addressed.  Now, another one has come up.
> I have been working with Nic Bellamy to figure out why his Asterisk  
> 1.2 systems
> have been freaking out after the upgrade.  The conversation started  
> here:
> http://lists.digium.com/pipermail/asterisk-dev/2008-May/032843.html
> I have determine what the problem is, and now must decide the most  
> appropriate fix.
> --- The security fix
> The security fix was to make it more difficult to abuse IAX2 in  
> Asterisk in a
> traffic amplification attack.
> 1) One problem in the code was that the destination call number was  
> never
> checked on incoming frames.  This made it very easy for an arbitrary  
> host to
> initiate an unauthenticated call in Asterisk, because it never had  
> to see any
> packets coming back.  The code now enforces that the destination  
> call number is
> correct.
> 2) Previously, Asterisk was very predictable in choosing call  
> numbers.  This
> would make the change in #1 not very useful, since guessing the  
> destination call
> number would be trivial.  So, the other change was to randomize the  
> choice of
> destination call numbers.
> #2 is what exposed the gross performance issue which has been  
> resolved.
> Now, we have an issue caused by change #1.
> --- The problem
> We changed the code to verify destination call numbers were  
> correct.  The exact
> logic in the change is very simple.  If the packet is a full frame,  
> it must
> carry an accurate destination call number.
> This unfortunately has introduced a race condition.  If a host sends  
> a 2nd frame
> in an IAX2 session before receiving the first frame from the other  
> side, we have
> a problem.  The receiver expects that second frame to contain the  
> destination
> call number.  Since it doesn't, the frame is rejected with an  
> INVAL.  If a 3rd
> frame is received that does contain the destination call number, it  
> is dropped,
> as the 2nd frame has not been received, and a VNAK is sent.  This  
> process never
> ends, resulting in a "INVAL/VNAK storm".
> --- The fix to the fix to the fix to the ....
> My initial patch was a bit of a hack.  I simply added some code to  
> ensure that
> the PING and LAGRQ frames did not get sent until the first frame is  
> received
> from the other end, since these were the cases that were triggering  
> the race
> condition.
> However, the biggest downside is that this only helps new  
> installations, and
> interoperability with previous Asterisk versions is still broken.
> My proposed fix is to change the logic for enforcing accurate  
> destination call
> numbers.  Since this was done to combat traffic amplification, I  
> propose that
> this enforcement is only done on frames that are responsible for  
> completing the
> handshake to start a call.  Essentially, that means _only_ doing this
> enforcement on an ACK, and no other full frames.
> The benefit to this is that we prevent traffic amplification from  
> hosts that
> have no way to figure out the destination call number, while doing  
> so in such a
> way that doesn't introduce problems with older Asterisk versions.
> --- Conclusion
> I plan on implementing and committing the proposed fix.  However, I  
> wanted to
> explain my logic and give everyone a chance to review all of the  
> information and
> disagree, in case I am missing something.
> Thanks for reading if you made it this far.  :)
I'm not comfortable with this.
The RFC draft says ACKs are optional.

(any subsequent fullframe can act as an ACK if it
has the appropriate sequence number)

So you can set up a call without using an ACK packet.

Simplest case is
- off you go.

It makes no sense to have a LAGRQ packet without a call set up .
Arguably it makes no sense to have a PING without a call.

For what it is worth, I think it would be better to
implement the initial 'hack' i.e. don't send LAGRQ  or  PING
untill the call is set up.
Then add an additional hack where these two don't have their
call numbers checked for backwards compatibility.


More information about the asterisk-dev mailing list