doh: clean up dangling DOH handles and memory on easy close

If you set the same URL for target as for DoH (and it isn't a DoH
server), like "https://example.com" in both, the easy handles used for
the DoH requests could be left "dangling" and end up not getting freed.

Reported-by: Paul Dreik
Closes #4366
This commit is contained in:
Daniel Stenberg 2019-09-16 16:38:01 +02:00
parent 3ad883aeda
commit 9bc44ff64d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 12 additions and 5 deletions

View File

@ -394,9 +394,9 @@ Curl_addrinfo *Curl_doh(struct connectdata *conn,
error:
curl_slist_free_all(data->req.doh.headers);
data->req.doh.headers = NULL;
curl_easy_cleanup(data->req.doh.probe[0].easy);
Curl_close(data->req.doh.probe[0].easy);
data->req.doh.probe[0].easy = NULL;
curl_easy_cleanup(data->req.doh.probe[1].easy);
Curl_close(data->req.doh.probe[1].easy);
data->req.doh.probe[1].easy = NULL;
return NULL;
}
@ -918,16 +918,17 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
/* remove DOH handles from multi handle and close them */
curl_multi_remove_handle(data->multi, data->req.doh.probe[0].easy);
Curl_close(data->req.doh.probe[0].easy);
data->req.doh.probe[0].easy = NULL;
curl_multi_remove_handle(data->multi, data->req.doh.probe[1].easy);
Curl_close(data->req.doh.probe[1].easy);
data->req.doh.probe[1].easy = NULL;
/* parse the responses, create the struct and return it! */
init_dohentry(&de);
rc = doh_decode(data->req.doh.probe[0].serverdoh.memory,
data->req.doh.probe[0].serverdoh.size,
data->req.doh.probe[0].dnstype,
&de);
free(data->req.doh.probe[0].serverdoh.memory);
Curl_safefree(data->req.doh.probe[0].serverdoh.memory);
if(rc) {
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc),
type2name(data->req.doh.probe[0].dnstype),
@ -937,7 +938,7 @@ CURLcode Curl_doh_is_resolved(struct connectdata *conn,
data->req.doh.probe[1].serverdoh.size,
data->req.doh.probe[1].dnstype,
&de);
free(data->req.doh.probe[1].serverdoh.memory);
Curl_safefree(data->req.doh.probe[1].serverdoh.memory);
if(rc2) {
infof(data, "DOH: %s type %s for %s\n", doh_strerror(rc2),
type2name(data->req.doh.probe[1].dnstype),

View File

@ -399,6 +399,12 @@ CURLcode Curl_close(struct Curl_easy *data)
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
/* Leave no dangling DOH handles behind */
Curl_close(data->req.doh.probe[0].easy);
Curl_close(data->req.doh.probe[1].easy);
free(data->req.doh.probe[0].serverdoh.memory);
free(data->req.doh.probe[1].serverdoh.memory);
/* destruct wildcard structures if it is needed */
Curl_wildcard_dtor(&data->wildcard);
Curl_freeset(data);