cURL / Mailing Lists / curl-library / Single Mail

curl-library

curl_easy_perform crash in Curl_do after Curl_reconnect_request has been called

From: Pasha Kuznetsov <b4uuzv3dgk_at_snkmail.com>
Date: Thu, 16 Dec 2010 14:30:25 -0600

Hello,

It seems that we have found a crash which happens when
curl_easy_perform is called, if Curl_do detects that the connection
which it tries to reuse is "dead" and successfully reconnects with
Curl_reconnect_request.

url.c:

CURLcode Curl_do(struct connectdata **connp, bool *done)
{
  CURLcode result=CURLE_OK;
  struct connectdata *conn = *connp;
  struct SessionHandle *data = conn->data;
  ...
  if(conn->handler->do_it) {
    ...
    if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
        ...
        if(!data->multi) {
          result = Curl_reconnect_request(connp);

          if(result == CURLE_OK) {
            /* ... finally back to actually retry the DO phase */
            result = conn->handler->do_it(conn, done);
  ...
  return result;
}

Please note that the original `conn' pointer is used after the
`connectdata' it points to has been closed/cleaned up by
Curl_reconnect_request.

I believe the code above should be modified along the following lines:
          ...
          result = Curl_reconnect_request(connp);
          conn = *connp;
          ...

Here's the part of our application log:

[curl_easy_perform...
    == Info: Re-using existing connection! (#0) with host xxx.xxx.xxx
    == Info: Connected to xxx.xxx.xxx (192.168.65.xxx) port 80 (#0)
    == Info: Send failure: Connection was aborted
    == Info: Failed sending HTTP POST request
    == Info: Re-used connection seems dead, get a new one
    == Info: Closing connection #0
    == Info: About to connect() to xxx.xxx.xxx port 80 (#0)
    == Info: Trying 192.168.65.xxx...
    == Info: connected
    == Info: Connected to xxx.xxx.xxx (192.168.65.xxx) port 80 (#0)
    ...
EXCEPTION_ACCESS_VIOLATION: The thread tried to read from or write to
a virtual address for which it does not have the appropriate access.

And here's the call stack from the corresponding crash dump (line
numbers are for curl 7.19.7, but the url.c from the git repo doesn't
seem to be different around the point of interest):

libcurlvc90.dll!checkheaders(SessionHandle * data=0x0776a460, const
char * thisheader=0x002979c0) Line 182
libcurlvc90.dll!Curl_http(connectdata * conn=0x060566d8, unsigned char
* done=0x0017cf4b) Line 2136
libcurlvc90.dll!Curl_do(connectdata * * connp=0x06057938, unsigned
char * done=0x0017cf4b) Line 5035
libcurlvc90.dll!Curl_perform(SessionHandle * data=0x06057901) Line 2635
libcurlvc90.dll!curl_easy_perform(void * curl=0x06057938) Line 557

The Curl_do location above is as follows:

        if(!data->multi) {
          result = Curl_reconnect_request(connp);

          if(result == CURLE_OK) {
            /* ... finally back to actually retry the DO phase */
> result = conn->handler->do_it(conn, done);
          }

-- 
Pasha Kuznetsov
MetaCommunications Engineering
http://www.metacommunications.com/
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
Received on 2010-12-16