We're seeing a crash in libcurl with the Windows system LDAP support
built in, where libcurl will attempt to free memory twice when a URL
parse fails.
This can be reproduced consistently using the command line tool with the
following URL:
"ldap://www.trustcenter.de/CN=TC%20TrustCenter%20Class%203%20CA%20II,O=TC%20TrustCenter%20GmbH,OU=rootcerts,DC=trustcenter,DC=de?certificateRevocationList?base?"
Windows is the only platform where we've seen the crash. We've tested
the attached patch on Mac OS X, 32-bit Windows and 64-bit Windows.
I believe I've followed the instructions for patch formatting and such,
but if I've gotten something wrong please let me know.
Thanks,
Geoff
>From 9b2944238d4a8613e70f8bbf8f04e2aba64c5f15 Mon Sep 17 00:00:00 2001
From: Geoff Beier <[email protected]>
Date: Tue, 20 Aug 2013 16:50:43 -0400
Subject: [PATCH] _ldap_url_parse2: prevent double-free from malformed LDAP
URL
When an error occurs parsing an LDAP URL, ludp->lud_attrs
can be freed even though it points into a string that is
freed elsewhere. This patch sets ludp->lud_attrs to NULL
in the event of an error to prevent the double-free.
---
lib/ldap.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/lib/ldap.c b/lib/ldap.c
index 2352715..540a15c 100644
--- a/lib/ldap.c
+++ b/lib/ldap.c
@@ -637,8 +637,10 @@ static int _ldap_url_parse2 (const struct connectdata
*conn, LDAPURLDesc *ludp)
if(*p && *p != '?') {
ludp->lud_scope = str2scope(p);
- if(ludp->lud_scope == -1)
+ if(ludp->lud_scope == -1) {
+ ludp->lud_attrs = NULL;
return LDAP_INVALID_SYNTAX;
+ }
LDAP_TRACE (("scope %d\n", ludp->lud_scope));
}
@@ -651,8 +653,10 @@ static int _ldap_url_parse2 (const struct connectdata
*conn, LDAPURLDesc *ludp)
q = strchr(p, '?');
if(q)
*q++ = '\0';
- if(!*p)
+ if(!*p) {
+ ludp->lud_attrs = NULL;
return LDAP_INVALID_SYNTAX;
+ }
ludp->lud_filter = p;
LDAP_TRACE (("filter '%s'\n", ludp->lud_filter));
@@ -664,8 +668,10 @@ static int _ldap_url_parse2 (const struct connectdata
*conn, LDAPURLDesc *ludp)
/* parse extensions
*/
ludp->lud_exts = split_str(p);
- if(!ludp->lud_exts)
+ if(!ludp->lud_exts) {
+ ludp->lud_attrs = NULL;
return LDAP_NO_MEMORY;
+ }
for(i = 0; ludp->lud_exts[i]; i++)
LDAP_TRACE (("exts[%d] '%s'\n", i, ludp->lud_exts[i]));
--
1.7.10.2 (Apple Git-33)
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html