Menu

#1005 curl_multi_socket_action() Crash after Teardown

closed
RTSP (4)
5
2014-08-17
2011-04-08
No

Hi,

We have recently implemented an RTSP client library using libcurl 7.21.4, but have found that in some instances a call to curl_multi_socket_action() with CURLMOPT_TIMERFUNCTION will cause a crash if any request is sent after a teardown has been issued. The process to invoke the crash would be to start a strream, stop it, and then to try start a stream again....

We tracked it down to Curl_getconnectinfo and have found that the SessionHandle parameter is set to NULL, which causes the crash as there is no check for this condition. As a temporary workaround we have added the following code at the start of the function to stop libcurl from crashing and it seems to work ok. Can you please check it out and let us know if the hack we put in place is ok ?

curl_socket_t Curl_getconnectinfo(struct SessionHandle *data,
struct connectdata **connp)
{
//TEMPORARY HACK UNTIL WE GET RESPONSE FROM CURL GUYS
if(data==NULL)
{
printf("\nCurl_getconnectinfo - data==NULL??");
return CURL_SOCKET_BAD;
}
curl_socket_t sockfd;
if((data->state.lastconnect != -1) &&
(data->state.connc->connects[data->state.lastconnect] != NULL)) {
struct connectdata *c =
data->state.connc->connects[data->state.lastconnect];
if(connp)
/* only store this if the caller cares for it */
*connp = c;
sockfd = c->sock[FIRSTSOCKET];
/* we have a socket connected, let's determine if the server shut down */
/* determine if ssl */
if(c->ssl[FIRSTSOCKET].use) {
/* use the SSL context */
if(!Curl_ssl_check_cxn(c))
return CURL_SOCKET_BAD; /* FIN received */
}
/* Minix 3.1 doesn't support any flags on recv; just assume socket is OK */
#ifdef MSG_PEEK
else {
/* use the socket */
char buf;
if(recv((RECV_TYPE_ARG1)c->sock[FIRSTSOCKET], (RECV_TYPE_ARG2)&buf,
(RECV_TYPE_ARG3)1, (RECV_TYPE_ARG4)MSG_PEEK) == 0) {
return CURL_SOCKET_BAD; /* FIN received */
}
}
#endif
}
else
return CURL_SOCKET_BAD;

return sockfd;
}

Also see backtrace below:

#0 0x080eb993 in Curl_getconnectinfo (data=0x0, connp=0xbfbfe300) at ../../curl-7.21.4/lib/connect.c:1127
1127 if((data->state.lastconnect != -1) &&
(gdb) bt
#0 0x080eb993 in Curl_getconnectinfo (data=0x0, connp=0xbfbfe300) at ../../curl-7.21.4/lib/connect.c:1127
#1 0x0810151d in RTSPConnIsDead (check=0x819c004) at ../../curl-7.21.4/lib/url.c:2763
#2 0x081018ec in ConnectionExists (data=0x81c4004, needle=0x8205004, usethis=0xbfbfe568) at ../../curl-7.21.4/lib/url.c:2935
#3 0x081048cf in create_conn (data=0x81c4004, in_connect=0x81c3390, async=0xbfbfe676) at ../../curl-7.21.4/lib/url.c:4976
#4 0x08104c2d in Curl_connect (data=0x81c4004, in_connect=0x81c3390, asyncp=0xbfbfe676, protocol_done=0xbfbfe675)
at ../../curl-7.21.4/lib/url.c:5148
#5 0x080ed1ea in multi_runsingle (multi=0x8175204, now={tv_sec = 15738, tv_usec = 288377}, easy=0x81c3384)
at ../../curl-7.21.4/lib/multi.c:1029
#6 0x080eefdd in multi_socket (multi=0x8175204, checkall=false, s=-1, ev_bitmask=0, running_handles=0xbfbfe764)
at ../../curl-7.21.4/lib/multi.c:2163
#7 0x080ef1e3 in curl_multi_socket_action (multi_handle=0x8175204, s=-1, ev_bitmask=0, running_handles=0xbfbfe764)
at ../../curl-7.21.4/lib/multi.c:2244
#8 0x0806f653 in NS_XTP::Manager::handleTimeout (this=0x8175100, timer_id=10) at xtp_manager.cpp:456
#9 0x080a56ef in NS_KERN::TimerManager::sendTimeout (this=0x8174100, timer_if=0x8175100, timer_id=10)
at kern_servermanagers.cpp:44
#10 0x080a95d7 in NS_KERN::TimerPriorityQueue::processZeroTimers (this=0x8174100) at kern_timerpriorityqueue.cpp:201
#11 0x080a9611 in NS_KERN::TimerPriorityQueue::processTimers (this=0x8174100) at kern_timerpriorityqueue.cpp:216
#12 0x080a5c1d in NS_KERN::StdKernel::handleRun (this=0x8174080) at kern_stdkernel.cpp:259
#13 0x080a4404 in NS_KERN::Kernel::run (this=0x8174080) at kern_kernel.cpp:164
#14 0x0807a3cf in NS_SRV::Server::run (this=0xbfbfe904) at srv_server.cpp:471
#15 0x0804ec44 in main (argc=2, argv=0xbfbfea5c) at main.cpp:237

Please let me know if you need any extra info...

Regards
Tinus van den Berg

Discussion

  • Daniel Stenberg

    Daniel Stenberg - 2011-04-11

    Right, as the code is written we can't have Curl_getconnectinfo() get called without the ->data pointer properly pointing to a SessionHandle, and when used in a multi interface handle it may not. Your fix should be enough.

    In the main source I'll do the check in Curl_rtsp_connisdead() instead (which is a new name of the function since your version) since that's the only caller that may pass in a NULL to the function.

     
  • Daniel Stenberg

    Daniel Stenberg - 2011-04-11
    • status: open --> closed
     
  • Daniel Stenberg

    Daniel Stenberg - 2011-04-11

    Thanks for the report, this problem is now fixed in the git repository.

    To try it out, you either checkout/update your git clone: http://curl.haxx.se/source.html

    or you try tomorrow's daily snapshot: http://curl.haxx.se/snapshots/