cURL / Mailing Lists / curl-library / Single Mail

curl-library

Dangling pointer problem

From: Patrick Monnerat <Patrick.Monnerat_at_datasphere.ch>
Date: Thu, 7 May 2015 18:10:26 +0200

 
I have found a very random dangling pointer problem: this occurs in FTP
when verbose mode is enabled.
 
The conn->ip_addr set at the start of the request is not valid anymore
if the DNS cache entry has been destroyed by the resolver at EPSV time.
I use the hostip6 resolver (no ares, no threaded).
 
Unfortunately, it is not easy to reproduce. But here is the
verbose+valgrind output (real IP address replaced for confidentiality).
-------------
> EPSV
* FTP 0x4fcc1c8 (line 1378) state change from STOP to PASV
* Connect data stream passively
* ftp_perform ends with SECONDARY: 0
* STATE: DO => DOING handle 0x4fb90e8; line 1291 (connection #0)
< 229 Entering Extended Passive Mode (|||30005|).
* Hostname in DNS cache was stale, zapped
* Trying 123.145.167.189...
==5828== Invalid read of size 4
==5828== at 0x4C1AC1D: Curl_printable_address (hostip.c:175)
==5828== by 0x4C30B1C: ftp_pasv_verbose (ftp.c:3558)
==5828== by 0x4C2DE76: ftp_state_pasv_resp (ftp.c:2091)
==5828== by 0x4C2FE92: ftp_statemach_act (ftp.c:3106)
==5828== by 0x4C6B661: Curl_pp_statemach (pingpong.c:131)
==5828== by 0x4C2FF38: ftp_multi_statemach (ftp.c:3140)
==5828== by 0x4C328DE: ftp_doing (ftp.c:4447)
==5828== by 0x4C3C877: Curl_protocol_doing (url.c:3525)
==5828== by 0x4C57299: multi_runsingle (multi.c:1373)
==5828== by 0x4C57FC8: curl_multi_perform (multi.c:1790)
==5828== by 0x4C4CDD9: easy_transfer (easy.c:715)
==5828== by 0x4C4CF77: easy_perform (easy.c:803)
==5828== Address 0x4fd33dc is 12 bytes inside a block of size 64 free'd
==5828== at 0x4A07577: free (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==5828== by 0x4C51090: curl_dofree (memdebug.c:334)
==5828== by 0x4C62411: Curl_freeaddrinfo (curl_addrinfo.c:87)
==5828== by 0x4C1B7B1: freednsentry (hostip.c:739)
==5828== by 0x4C54537: hash_element_dtor (hash.c:40)
==5828== by 0x4C541F2: Curl_llist_remove (llist.c:132)
==5828== by 0x4C54A7D: Curl_hash_delete (hash.c:194)
==5828== by 0x4C1AF5E: fetch_addr (hostip.c:319)
==5828== by 0x4C1B20A: Curl_resolv (hostip.c:458)
==5828== by 0x4C2DD94: ftp_state_pasv_resp (ftp.c:2057)
==5828== by 0x4C2FE92: ftp_statemach_act (ftp.c:3106)
==5828== by 0x4C6B661: Curl_pp_statemach (pingpong.c:131)
-----------
More similar valgind events follow.

How would you fix it?
- live with the dangling pointer and have a simpler verbose output.
- copy the addrinfo to conn->ip_addr rather than pointing to the DNS
cache data.
- Keep the DNS cache entry with "inuse" bumped.
- Something else.

To try to make it occur:

curl_easy_setopt(h, CURLOPT_DNS_CACHE_TIMEOUT, 1L);
curl_easy_setopt(h, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(h, CURLOPT_URL, "ftp://yourtestserver/");
curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, nooutput);

for (;;) {
        res = curl_easy_perform(h);
        if (res == CURLE_OK)
                sleep(2);
        else
                break;
}

Note: I initially discovered it on the OS/400 since after many requests,
conn->ip_addr->ai_addr is NULL and thus segfaults.

Patrick

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2015-05-07