]> granicus.if.org Git - curl/commitdiff
doh: clean up dangling DOH handles and memory on easy close
authorDaniel Stenberg <daniel@haxx.se>
Mon, 16 Sep 2019 14:38:01 +0000 (16:38 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 16 Sep 2019 15:31:56 +0000 (17:31 +0200)
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

lib/doh.c
lib/url.c

index 6f06d0a35ccb7146d07c1ef81ced3b7d891b490e..e97e4fe7a2bd7cefa73cf8790d0f014308e9759c 100644 (file)
--- a/lib/doh.c
+++ b/lib/doh.c
@@ -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),
index b7cf7bedd327f96a4390f543db6a75e068f72aea..94dc9b8b2be04ebdbb5c8744227cbebdda2b4bcf 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -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);