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