]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
conn: fix hostname move on connection reuse
authorStefan Eissing <stefan@eissing.org>
Fri, 10 Oct 2025 07:48:52 +0000 (09:48 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 10 Oct 2025 21:45:58 +0000 (23:45 +0200)
When reusing a connection, the `host` and `conn_to_host` hostname
structs are moved from the template connection onto the existing one.

There was a NULLing of a tempplate member missing in `conn_to_host`
which could then lead to a double free.

Make this struct move into a static function, doing the correct
thing for both `struct hostname` in a connection.

Reported-by: Joshua Rogers
Closes #18995

lib/url.c

index 6a433b09efd1cc6a169d1218656000fddd9ddd11..6d69fc11bf88c8d9da1ef71421e13365930fde48 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -3286,6 +3286,14 @@ static CURLcode resolve_server(struct Curl_easy *data,
   return CURLE_OK;
 }
 
+static void url_move_hostname(struct hostname *dest, struct hostname *src)
+{
+  Curl_safefree(dest->rawalloc);
+  Curl_free_idnconverted_hostname(dest);
+  *dest = *src;
+  memset(src, 0, sizeof(*src));
+}
+
 /*
  * Cleanup the connection `temp`, just allocated for `data`, before using the
  * previously `existing` one for `data`. All relevant info is copied over
@@ -3340,15 +3348,9 @@ static void reuse_conn(struct Curl_easy *data,
    *       used the original hostname in SNI to negotiate? Do we send
    *       requests for another host through the different SNI?
    */
-  Curl_free_idnconverted_hostname(&existing->host);
-  Curl_free_idnconverted_hostname(&existing->conn_to_host);
-  Curl_safefree(existing->host.rawalloc);
-  Curl_safefree(existing->conn_to_host.rawalloc);
-  existing->host = temp->host;
-  temp->host.rawalloc = NULL;
-  temp->host.encalloc = NULL;
-  existing->conn_to_host = temp->conn_to_host;
-  temp->conn_to_host.rawalloc = NULL;
+  url_move_hostname(&existing->host, &temp->host);
+  url_move_hostname(&existing->conn_to_host, &temp->conn_to_host);
+
   existing->conn_to_port = temp->conn_to_port;
   existing->remote_port = temp->remote_port;
   free(existing->hostname_resolve);