From 05564e750e8f0c79016c680f301ce251e6e86155 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Oct 2018 09:58:04 +0200 Subject: multi: avoid double-free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Curl_follow() no longer frees the string. Make sure it happens in the caller function, like we normally handle allocations. This bug was introduced with the use of the URL API internally, it has never been in a release version Reported-by: Dario Weißer Closes #3149 --- lib/multi.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'lib/multi.c') diff --git a/lib/multi.c b/lib/multi.c index 9485f7857..7c691a1b8 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1707,7 +1707,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, char *newurl = NULL; followtype follow = FOLLOW_NONE; CURLcode drc; - bool retry = FALSE; drc = Curl_retry_request(data->easy_conn, &newurl); if(drc) { @@ -1715,19 +1714,16 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, result = drc; stream_error = TRUE; } - else - retry = (newurl)?TRUE:FALSE; Curl_posttransfer(data); drc = multi_done(&data->easy_conn, result, FALSE); /* When set to retry the connection, we must to go back to * the CONNECT state */ - if(retry) { + if(newurl) { if(!drc || (drc == CURLE_SEND_ERROR)) { follow = FOLLOW_RETRY; drc = Curl_follow(data, newurl, follow); - newurl = NULL; /* freed by Curl_follow() */ if(!drc) { multistate(data, CURLM_STATE_CONNECT); rc = CURLM_CALL_MULTI_PERFORM; @@ -1987,16 +1983,14 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, else follow = FOLLOW_RETRY; result = multi_done(&data->easy_conn, CURLE_OK, FALSE); - if(result) - /* Curl_follow() would otherwise free this */ - free(newurl); - else { + if(!result) { result = Curl_follow(data, newurl, follow); if(!result) { multistate(data, CURLM_STATE_CONNECT); rc = CURLM_CALL_MULTI_PERFORM; } } + free(newurl); } else { /* after the transfer is done, go DONE */ @@ -2008,6 +2002,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, newurl = data->req.location; data->req.location = NULL; result = Curl_follow(data, newurl, FOLLOW_FAKE); + free(newurl); if(result) { stream_error = TRUE; result = multi_done(&data->easy_conn, result, TRUE); -- cgit v1.2.1