curl-library
[patch] libcurl 7.12.2-20040917 and CURLOPT_VERBOSE may read free()ed data
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