Summary:ASTERISK-12538: crash if hangup during sip_read
Reporter:Travis Hein (travishein)Labels:
Date Opened:2008-08-07 21:26:41Date Closed:2008-08-20 10:29:10
Versions:Frequency of
Environment:Attachments:( 0) bt.txt
( 1) console.txt
Description:This one might be similar to ASTERISK-12537, although this time it appears to crash from within the sip_read. It is almost as if the application that was invoked from the realtime_exec entered a state of waiting for an input from the user, but the user hung up during this waiting period, so when the system starts looking for the response after the wait period, in this case the channel had closed,

At least that's my view from the outside impression, the last line printed to teh console was:

WARNING[6784]: rtp.c:1140 ast_rtp_read: RTP Read error: Socket operation on non-socket.  Hanging up.

currently on 1.4.20rc2
Comments:By: Leif Madsen (lmadsen) 2008-08-11 14:22:18

I think getting the output of the console prior to the crash, along with the sip history would be helpful.

Could you provide that for us?


By: Travis Hein (travishein) 2008-08-16 00:29:48

I attached the output that was captured from the console at the time of the crash. unfortunately this small bit is all that we had.

By: Mark Michelson (mmichelson) 2008-08-20 09:25:54

The backtrace shows that there was an attempted dereference of a NULL pointer. The problem may be as easy to fix as making sure that the frame read from sip_rtp_read is non-NULL before continuing. I'll take a closer look at the semantics and give more feedback soon.

By: Mark Michelson (mmichelson) 2008-08-20 09:57:21

The console trace that you provided showed that for some reason, recvfrom() failed when trying to read RTP because it thought that the file descriptor passed in was not a socket. The problem is that the rtp socket file descriptor is always initialized using socket(2), so it can't be that we're trying to read from an uninitialized file descriptor.

I did notice, however, that the return value of socket(2) is pretty much ignored, so error handling needs to be handled better and earlier in case something wrong occurs when attempting to create the socket. The problem is that I thought that if  a call to socket(2) were to fail and later we attempted to read from it, errno would be set to EBADF instead of ENOTSOCK. I can't seem to find definitive documentation on this, though.

Also, since sip_rtp_read has the potential to return NULL, it needs to be handled properly in sip_read. What I will do is add proper error checking to all places which initialize the rtp socket and add error checking to sip_read so that the possible NULL return does not cause a catastrophic failure.

By: Mark Michelson (mmichelson) 2008-08-20 10:15:28

Actually I was mistaken about the socket(2) lack of error handling. It appears that if the recvfrom(2) was called on a file descriptor which was not a socket, it either means a memory corruption of the rtp structure or that the kernel is not handling file descriptors properly.

I'll still add the error-handling to sip_read, and I believe I'll close this bug after the fact, too. If this occurs again, it would be helpful to run Asterisk under valgrind to see if there is some corruption of the rtp structure.

By: Digium Subversion (svnbot) 2008-08-20 10:29:08

Repository: asterisk
Revision: 139015

U   branches/1.4/channels/chan_sip.c

r139015 | mmichelson | 2008-08-20 10:29:07 -0500 (Wed, 20 Aug 2008) | 6 lines

sip_read should properly handle a NULL return from sip_rtp_read.

(closes issue ASTERISK-12538)
Reported by: travishein