cURL / Mailing Lists / curl-library / Single Mail

curl-library

[patch] libcurl 7.12.2-20040917 and CURLOPT_VERBOSE may read free()ed data

From: Bertrand Demiddelaer <bdemiddelaer_at_denyall.com>
Date: Tue, 21 Sep 2004 18:59:28 +0200

Hi,

I'm using licurl-7.12.2-20040917 on a monoprocess/monothread application
with curl_multi et curl_share interfaces (for dns). I noticed that
enabling CURLOPT_VERBOSE could cause this kind of report with valgrind:

==29530== Invalid read of size 4
==29530== at 0x807F1A4: Curl_printable_address (hostip.c:191)
==29530== by 0x8083CD4: verboseconnect (url.c:2001)
==29530== by 0x8085AFB: SetupConnection (url.c:3383)
==29530== by 0x8085B69: Curl_connect (url.c:3422)
==29530== by 0x807E9F9: curl_multi_perform (multi.c:372)
==29530== Address 0x1B9CDB3C is 20 bytes inside a block of size 48 free'd
==29530== at 0x1B9023F3: free (vg_replace_malloc.c:153)
==29530== by 0x809066D: Curl_freeaddrinfo (hostip4.c:110)
==29530== by 0x807F5F8: freednsentry (hostip.c:496)
==29530== by 0x807E23C: hash_element_dtor (hash.c:60)
==29530== by 0x808F0AC: Curl_llist_remove (llist.c:114)

Here's a patch which seems to solve this problem for me. All curl tests
passed, except for test 506. I guess the failure of this test is
triggered by the calls to Curl_share_lock() and Curl_share_unlock() I
added around a "lonely" dns->inuse++ (these new calls were not needed to
solve my problem, but I guess they were missing. May be I'm wrong).

Any other ideas or suggestions ?

Thanks for helping :-)

--- lib/hostip.c.00 Tue Sep 21 17:58:44 2004
+++ lib/hostip.c Tue Sep 21 17:59:23 2004
@@ -459,7 +459,11 @@
     }
   }
   else {
+ if(data->share)
+ Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
     dns->inuse++; /* we use it! */
+ if(data->share)
+ Curl_share_unlock(data, CURL_LOCK_DATA_DNS);
     rc = CURLRESOLV_RESOLVED;
   }
 
--- lib/url.c.00 Tue Sep 21 17:58:36 2004
+++ lib/url.c Tue Sep 21 18:13:30 2004
@@ -1510,6 +1510,8 @@
   Curl_safefree(conn->async.os_specific);
 #endif
 
+ Curl_safefree(conn->ip_dispname);
+
   Curl_free_ssl_config(&conn->ssl_config);
 
   free(conn); /* free all the connection oriented data */
@@ -1997,11 +1999,18 @@
   struct SessionHandle *data = conn->data;
   char addrbuf[256];
 
+ /* paranoia */
+ addrbuf[0]=0;
+
   /* Get a printable version of the network address. */
- Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
+ if (!conn->ip_dispname) {
+ Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf));
+ if (addrbuf[0])
+ conn->ip_dispname=strdup(addrbuf);
+ }
   infof(data, "Connected to %s (%s) port %d\n",
         conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname,
- addrbuf[0] ? addrbuf : "??", conn->port);
+ conn->ip_dispname ? conn->ip_dispname : "??", conn->port);
 }
 
 /*
--- lib/urldata.h.00 Tue Sep 21 17:54:20 2004
+++ lib/urldata.h Tue Sep 21 17:56:51 2004
@@ -445,9 +445,11 @@
 #define PROT_FTPS (1<<9)
 #define PROT_SSL (1<<10) /* protocol requires SSL */
 
- /* the particular host we use, in two different ways */
+ /* the particular host we use, in three different ways */
   struct Curl_dns_entry *dns_entry;
   Curl_addrinfo *ip_addr; /* the particular IP we connected to */
+ char *ip_dispname; /* ip_addr can be free()ed and break latter
+ verboseconnect() calls */
 
   char protostr[16]; /* store the protocol string in this buffer */
 
Received on 2004-09-21