Submitted By: Xi Ruoyao Initial Package Version: 7.71.1 Origin: Upstream https://github.com/curl/curl/commit/3c9e021f and self (backport) Upstream Status: Applied Description: Fixes CVE-2020-8231: libcurl: wrong connect-only connection. diff --color -Nuar curl-7.71.1/lib/connect.c curl-7.71.1-patched/lib/connect.c --- curl-7.71.1/lib/connect.c 2020-06-28 06:03:53.000000000 +0800 +++ curl-7.71.1-patched/lib/connect.c 2020-08-21 00:58:06.525348128 +0800 @@ -1363,15 +1363,15 @@ } 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 @@ * - 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; diff --color -Nuar curl-7.71.1/lib/easy.c curl-7.71.1-patched/lib/easy.c --- curl-7.71.1/lib/easy.c 2020-06-28 06:03:53.000000000 +0800 +++ curl-7.71.1-patched/lib/easy.c 2020-08-21 00:58:06.525348128 +0800 @@ -838,8 +838,7 @@ /* 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; diff --color -Nuar curl-7.71.1/lib/multi.c curl-7.71.1-patched/lib/multi.c --- curl-7.71.1/lib/multi.c 2020-06-30 18:28:19.000000000 +0800 +++ curl-7.71.1-patched/lib/multi.c 2020-08-21 00:58:06.526347915 +0800 @@ -455,6 +455,7 @@ 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 @@ 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); diff --color -Nuar curl-7.71.1/lib/url.c curl-7.71.1-patched/lib/url.c --- curl-7.71.1/lib/url.c 2020-06-30 18:26:39.000000000 +0800 +++ curl-7.71.1-patched/lib/url.c 2020-08-21 00:58:06.527347701 +0800 @@ -630,7 +630,7 @@ 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 */ diff --color -Nuar curl-7.71.1/lib/urldata.h curl-7.71.1-patched/lib/urldata.h --- curl-7.71.1/lib/urldata.h 2020-06-30 18:26:39.000000000 +0800 +++ curl-7.71.1-patched/lib/urldata.h 2020-08-21 00:58:06.528347488 +0800 @@ -1300,7 +1300,7 @@ /* 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 */