Recently, we have supplied a couple of patches for a customer 
installation that are meant to solve proxy random crashes. The first 
incident seems to point to failure in reassembly of TCP segments. 
Whether the error was caused by a bug in sipXtackLib packet reassembly 
algorithm or by a corruption in the packet due to low level transport 
failure is yet to be determined. However, core dumps suggest that such 
incidents could cause the SIP parser to crash at the point when the SIP 
stack is trying to match messages with transactions. In this case, 
parsing of the via header caused a segmentation fault. The via in the 
SIPMessage looks like this.

Via: SIP/2.0/UDP 
10.10.5.93:506���M��##6###6#####�#�####Z#D##E##(6�@#@#�e�##0

So I fired a new CPP UNIT test case against this via header hoping to 
reproduce a crash but it didn't. Parser went fine with it. In fact 
getting the via of SIP message even returned TRUE indicating nothing 
about the error! Clearly, no check is being done in the parser as to 
which bytes can legally be present in a SIP header. As to what caused 
the crash is still unknown at this point and my main suspect is that 
corruption in SIP messages allowed some buffer overruns to happen. 
However, if only sanity checks where up, the crash could have been 
avoided and prevented from being propagated into the transaction layer.

Incident number 2 of proxy crashing due to parser error is pretty 
straight forward because it can be reproduced using a regression test 
case. It happens when multiple packets are packed together in a single 
TCP segment. In this particular incident, the TCP segment contained 3 
INVITEs and 1 ACK request. The SDP in the INVITEs are not terminated by 
an empty line but has the correct content-length. It is perfectly 
formatted. However, the tokenizer of the SDP expects either a blank line 
as the boundary or if the string is terminated by '\000' both of which 
are not present. Blank line is not present because SDP ended at the last 
line and was properly represented by content-length and '\000' is not 
present because the next character after the SDP is already the 
beginning of the next packet in the combo segment. This caused the 
parser to overrun some bytes from the next packet resulting to corrupt 
SIP Message. Yet again, parser crashed the system.

My proposal is to create a new task for this iteration to produce a 
regression/crash test against the following parsers to catch more of 
these possible proxy crashers.

1. Contact/From/To parsing including UTF 8
2. URI parsing - including IPV6 host parsing
3. Via parsing - including IPV6 host parsing
4. Route/Record-Route parsing - including IPV6
5. Request-Line/Status-Line parsing
6. Buffer overflow checks against integer headers (CSeq, Expires etc)
7. Improve NameValueTokenizer to respect boundaries instead of 
positioning snipers in the front of the stack to prevent attacks.


If I missed something, just add to the list.

Modify parser accordingly based on results of these checks. The 
NameValueTokenizer needs to be replaced by a boundary safe 
implementation in main. I recommend boost::tokenizer

I would welcome and appreciate some comments.


Lastly my future plan is to introduce better exception handling in SIP 
Message parsing and be able to respond back with a 400 with exactly 
which header the parser thinks is bad. Something like the code below.

SipMessage msg;
try
{
msg.read(socket);
}
catch(SipParserException& e)
{
if (msg.isResponsePossible())
{
SipMessage response;
msg.createBadRequestResponse(response, e.what());
transport.send(response);
}
}



Joegen


_______________________________________________
sipx-dev mailing list
[email protected]
List Archive: http://list.sipfoundry.org/archive/sipx-dev/

Reply via email to