mirror of
https://github.com/moparisthebest/curl
synced 2024-08-13 17:03:50 -04:00
Curl_easy: remember last connection by id, not by pointer
CVE-2020-8231 Bug: https://curl.haxx.se/docs/CVE-2020-8231.html Reported-by: Marc Aldorasi Closes #5824
This commit is contained in:
parent
687908c6e6
commit
3c9e021f86
@ -1363,15 +1363,15 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct connfind {
|
struct connfind {
|
||||||
struct connectdata *tofind;
|
long id_tofind;
|
||||||
bool found;
|
struct connectdata *found;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int conn_is_conn(struct connectdata *conn, void *param)
|
static int conn_is_conn(struct connectdata *conn, void *param)
|
||||||
{
|
{
|
||||||
struct connfind *f = (struct connfind *)param;
|
struct connfind *f = (struct connfind *)param;
|
||||||
if(conn == f->tofind) {
|
if(conn->connection_id == f->id_tofind) {
|
||||||
f->found = TRUE;
|
f->found = conn;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
* - that is associated with a multi handle, and whose connection
|
||||||
* was detached with CURLOPT_CONNECT_ONLY
|
* was detached with CURLOPT_CONNECT_ONLY
|
||||||
*/
|
*/
|
||||||
if(data->state.lastconnect && (data->multi_easy || data->multi)) {
|
if((data->state.lastconnect_id != -1) && (data->multi_easy || data->multi)) {
|
||||||
struct connectdata *c = data->state.lastconnect;
|
struct connectdata *c;
|
||||||
struct connfind find;
|
struct connfind find;
|
||||||
find.tofind = data->state.lastconnect;
|
find.id_tofind = data->state.lastconnect_id;
|
||||||
find.found = FALSE;
|
find.found = NULL;
|
||||||
|
|
||||||
Curl_conncache_foreach(data, data->multi_easy?
|
Curl_conncache_foreach(data, data->multi_easy?
|
||||||
&data->multi_easy->conn_cache:
|
&data->multi_easy->conn_cache:
|
||||||
&data->multi->conn_cache, &find, conn_is_conn);
|
&data->multi->conn_cache, &find, conn_is_conn);
|
||||||
|
|
||||||
if(!find.found) {
|
if(!find.found) {
|
||||||
data->state.lastconnect = NULL;
|
data->state.lastconnect_id = -1;
|
||||||
return CURL_SOCKET_BAD;
|
return CURL_SOCKET_BAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c = find.found;
|
||||||
if(connp) {
|
if(connp) {
|
||||||
/* only store this if the caller cares for it */
|
/* only store this if the caller cares for it */
|
||||||
*connp = c;
|
*connp = c;
|
||||||
|
@ -838,8 +838,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
|||||||
|
|
||||||
/* the connection cache is setup on demand */
|
/* the connection cache is setup on demand */
|
||||||
outcurl->state.conn_cache = NULL;
|
outcurl->state.conn_cache = NULL;
|
||||||
|
outcurl->state.lastconnect_id = -1;
|
||||||
outcurl->state.lastconnect = NULL;
|
|
||||||
|
|
||||||
outcurl->progress.flags = data->progress.flags;
|
outcurl->progress.flags = data->progress.flags;
|
||||||
outcurl->progress.callback = data->progress.callback;
|
outcurl->progress.callback = data->progress.callback;
|
||||||
|
@ -455,6 +455,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi,
|
|||||||
data->state.conn_cache = &data->share->conn_cache;
|
data->state.conn_cache = &data->share->conn_cache;
|
||||||
else
|
else
|
||||||
data->state.conn_cache = &multi->conn_cache;
|
data->state.conn_cache = &multi->conn_cache;
|
||||||
|
data->state.lastconnect_id = -1;
|
||||||
|
|
||||||
#ifdef USE_LIBPSL
|
#ifdef USE_LIBPSL
|
||||||
/* Do the same for PSL. */
|
/* Do the same for PSL. */
|
||||||
@ -677,11 +678,11 @@ static CURLcode multi_done(struct Curl_easy *data,
|
|||||||
CONNCACHE_UNLOCK(data);
|
CONNCACHE_UNLOCK(data);
|
||||||
if(Curl_conncache_return_conn(data, conn)) {
|
if(Curl_conncache_return_conn(data, conn)) {
|
||||||
/* remember the most recently used connection */
|
/* remember the most recently used connection */
|
||||||
data->state.lastconnect = conn;
|
data->state.lastconnect_id = conn->connection_id;
|
||||||
infof(data, "%s\n", buffer);
|
infof(data, "%s\n", buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
data->state.lastconnect = NULL;
|
data->state.lastconnect_id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Curl_safefree(data->state.buffer);
|
Curl_safefree(data->state.buffer);
|
||||||
@ -693,7 +694,7 @@ static int close_connect_only(struct connectdata *conn, void *param)
|
|||||||
{
|
{
|
||||||
struct Curl_easy *data = param;
|
struct Curl_easy *data = param;
|
||||||
|
|
||||||
if(data->state.lastconnect != conn)
|
if(data->state.lastconnect_id != conn->connection_id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(conn->data != data)
|
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 */
|
/* Remove the association between the connection and the handle */
|
||||||
Curl_detach_connnection(data);
|
Curl_detach_connnection(data);
|
||||||
|
|
||||||
if(data->state.lastconnect) {
|
if(data->state.lastconnect_id != -1) {
|
||||||
/* Mark any connect-only connection for closure */
|
/* Mark any connect-only connection for closure */
|
||||||
Curl_conncache_foreach(data, data->state.conn_cache,
|
Curl_conncache_foreach(data, data->state.conn_cache,
|
||||||
data, &close_connect_only);
|
data, &close_connect_only);
|
||||||
|
@ -630,7 +630,7 @@ CURLcode Curl_open(struct Curl_easy **curl)
|
|||||||
Curl_initinfo(data);
|
Curl_initinfo(data);
|
||||||
|
|
||||||
/* most recent connection is not yet defined */
|
/* most recent connection is not yet defined */
|
||||||
data->state.lastconnect = NULL;
|
data->state.lastconnect_id = -1;
|
||||||
|
|
||||||
data->progress.flags |= PGRS_HIDE;
|
data->progress.flags |= PGRS_HIDE;
|
||||||
data->state.current_speed = -1; /* init to negative == impossible */
|
data->state.current_speed = -1; /* init to negative == impossible */
|
||||||
|
@ -1300,7 +1300,7 @@ struct UrlState {
|
|||||||
/* buffers to store authentication data in, as parsed from input options */
|
/* buffers to store authentication data in, as parsed from input options */
|
||||||
struct curltime keeps_speed; /* for the progress meter really */
|
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 */
|
struct dynbuf headerb; /* buffer to store headers in */
|
||||||
|
|
||||||
char *buffer; /* download buffer */
|
char *buffer; /* download buffer */
|
||||||
|
Loading…
Reference in New Issue
Block a user