]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
Curl_easy: remember last connection by id, not by pointer
authorDaniel Stenberg <daniel@haxx.se>
Sun, 16 Aug 2020 09:34:35 +0000 (11:34 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 17 Aug 2020 12:33:09 +0000 (14:33 +0200)
CVE-2020-8231

Bug: https://curl.haxx.se/docs/CVE-2020-8231.html

Reported-by: Marc Aldorasi
Closes #5824

lib/connect.c
lib/easy.c
lib/multi.c
lib/url.c
lib/urldata.h

index 313c23315dd7d4c6b6b32e3c91d2c1caf1dddb17..b000b1b2c2b788efc312dc765eecc759c4d0be60 100644 (file)
@@ -1363,15 +1363,15 @@ CURLcode Curl_connecthost(struct connectdata *conn,  /* context */
 }
 
 struct connfind {
-  struct connectdata *tofind;
-  bool found;
+  long id_tofind;
+  struct connectdata *found;
 };
 
 static int conn_is_conn(struct connectdata *conn, void *param)
 {
   struct connfind *f = (struct connfind *)param;
-  if(conn == f->tofind) {
-    f->found = TRUE;
+  if(conn->connection_id == f->id_tofind) {
+    f->found = conn;
     return 1;
   }
   return 0;
@@ -1393,21 +1393,22 @@ curl_socket_t Curl_getconnectinfo(struct Curl_easy *data,
    * - that is associated with a multi handle, and whose connection
    *   was detached with CURLOPT_CONNECT_ONLY
    */
-  if(data->state.lastconnect && (data->multi_easy || data->multi)) {
-    struct connectdata *c = data->state.lastconnect;
+  if((data->state.lastconnect_id != -1) && (data->multi_easy || data->multi)) {
+    struct connectdata *c;
     struct connfind find;
-    find.tofind = data->state.lastconnect;
-    find.found = FALSE;
+    find.id_tofind = data->state.lastconnect_id;
+    find.found = NULL;
 
     Curl_conncache_foreach(data, data->multi_easy?
                            &data->multi_easy->conn_cache:
                            &data->multi->conn_cache, &find, conn_is_conn);
 
     if(!find.found) {
-      data->state.lastconnect = NULL;
+      data->state.lastconnect_id = -1;
       return CURL_SOCKET_BAD;
     }
 
+    c = find.found;
     if(connp) {
       /* only store this if the caller cares for it */
       *connp = c;
index 292cca7f6f0bdc8585e20641b345508cc06ae5a9..a69eb9e567596590c26cca664fc9af9a1e8ce74b 100644 (file)
@@ -838,8 +838,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
 
   /* the connection cache is setup on demand */
   outcurl->state.conn_cache = NULL;
-
-  outcurl->state.lastconnect = NULL;
+  outcurl->state.lastconnect_id = -1;
 
   outcurl->progress.flags    = data->progress.flags;
   outcurl->progress.callback = data->progress.callback;
index b3a75e1374871cac4c208542310be7ccaf8eee87..3c7fb85ed8319ad2675413fad8c18fb3680e9f07 100644 (file)
@@ -455,6 +455,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
     data->state.conn_cache = &data->share->conn_cache;
   else
     data->state.conn_cache = &multi->conn_cache;
+  data->state.lastconnect_id = -1;
 
 #ifdef USE_LIBPSL
   /* Do the same for PSL. */
@@ -677,11 +678,11 @@ static CURLcode multi_done(struct Curl_easy *data,
     CONNCACHE_UNLOCK(data);
     if(Curl_conncache_return_conn(data, conn)) {
       /* remember the most recently used connection */
-      data->state.lastconnect = conn;
+      data->state.lastconnect_id = conn->connection_id;
       infof(data, "%s\n", buffer);
     }
     else
-      data->state.lastconnect = NULL;
+      data->state.lastconnect_id = -1;
   }
 
   Curl_safefree(data->state.buffer);
@@ -693,7 +694,7 @@ static int close_connect_only(struct connectdata *conn, void *param)
 {
   struct Curl_easy *data = param;
 
-  if(data->state.lastconnect != conn)
+  if(data->state.lastconnect_id != conn->connection_id)
     return 0;
 
   if(conn->data != data)
@@ -805,7 +806,7 @@ CURLMcode curl_multi_remove_handle(struct Curl_multi *multi,
   /* Remove the association between the connection and the handle */
   Curl_detach_connnection(data);
 
-  if(data->state.lastconnect) {
+  if(data->state.lastconnect_id != -1) {
     /* Mark any connect-only connection for closure */
     Curl_conncache_foreach(data, data->state.conn_cache,
                            data, &close_connect_only);
index a98aab27f2b23db96970627f58811867bcadd2da..150667aa97fd1cfd4e15520f2bc0477dffe65880 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -630,7 +630,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
     Curl_initinfo(data);
 
     /* most recent connection is not yet defined */
-    data->state.lastconnect = NULL;
+    data->state.lastconnect_id = -1;
 
     data->progress.flags |= PGRS_HIDE;
     data->state.current_speed = -1; /* init to negative == impossible */
index 8ddb580c8965358ecfe3f7219cef111493e54d48..0ae92692759ba2d71b62c846bd74b0b44e9635f3 100644 (file)
@@ -1300,7 +1300,7 @@ struct UrlState {
   /* buffers to store authentication data in, as parsed from input options */
   struct curltime keeps_speed; /* for the progress meter really */
 
-  struct connectdata *lastconnect; /* The last connection, NULL if undefined */
+  long lastconnect_id; /* The last connection, -1 if undefined */
   struct dynbuf headerb; /* buffer to store headers in */
 
   char *buffer; /* download buffer */