From d10b544f74f42e3fbfa39f1dd7f44bde44842c8d Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Mon, 12 Jun 2023 22:20:39 +0200 Subject: [PATCH] Fix CVE-2020-8231 Merge: curl/curl@3c9e021f86872baae412 Note: Member order in 'connfind' has been left identical, except for that 'found' (now 'id_tofind') is a long. Code however, should pad it to a 4 byte boundary. Size of 'UrlState' has also remained unchanged, the 'connectdata' member has been renamed to 'lastconnect_id', and its type has been changed to 'long'. Additional padding has been incorporated to make sure the structure's size remains the same as that of the game, may we ever hook compiled code with ours. --- r5dev/thirdparty/curl/connect.c | 19 ++++++++++--------- r5dev/thirdparty/curl/easy.c | 2 +- r5dev/thirdparty/curl/multi.c | 5 +++-- r5dev/thirdparty/curl/url.c | 2 +- r5dev/thirdparty/curl/urldata.h | 5 ++++- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/r5dev/thirdparty/curl/connect.c b/r5dev/thirdparty/curl/connect.c index 63ec50fd..86ed6250 100644 --- a/r5dev/thirdparty/curl/connect.c +++ b/r5dev/thirdparty/curl/connect.c @@ -1195,15 +1195,15 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ } struct connfind { - struct connectdata *tofind; - bool found; + struct connectdata * found; + long id_tofind; }; 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; @@ -1227,21 +1227,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->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 --git a/r5dev/thirdparty/curl/easy.c b/r5dev/thirdparty/curl/easy.c index 2b5f972e..3284d2a8 100644 --- a/r5dev/thirdparty/curl/easy.c +++ b/r5dev/thirdparty/curl/easy.c @@ -886,7 +886,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; diff --git a/r5dev/thirdparty/curl/multi.c b/r5dev/thirdparty/curl/multi.c index b24ce19d..e7651976 100644 --- a/r5dev/thirdparty/curl/multi.c +++ b/r5dev/thirdparty/curl/multi.c @@ -402,6 +402,7 @@ CURLMcode curl_multi_add_handle(struct Curl_multi *multi, /* Point to the multi's connection cache */ data->state.conn_cache = &multi->conn_cache; + data->state.lastconnect_id = -1; /* This adds the new entry at the 'end' of the doubly-linked circular list of Curl_easy structs to try and maintain a FIFO queue so @@ -624,7 +625,7 @@ static CURLcode multi_done(struct connectdata **connp, /* the connection is no longer in use */ if(ConnectionDone(data, conn)) { /* remember the most recently used connection */ - data->state.lastconnect = conn; + data->state.lastconnect_id = conn->connection_id; infof(data, "Connection #%ld to host %s left intact\n", conn->connection_id, @@ -634,7 +635,7 @@ static CURLcode multi_done(struct connectdata **connp, conn->host.dispname); } else - data->state.lastconnect = NULL; + data->state.lastconnect_id = -1; } *connp = NULL; /* to make the caller of this function better detect that diff --git a/r5dev/thirdparty/curl/url.c b/r5dev/thirdparty/curl/url.c index 499395c9..4711746c 100644 --- a/r5dev/thirdparty/curl/url.c +++ b/r5dev/thirdparty/curl/url.c @@ -665,7 +665,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 */ diff --git a/r5dev/thirdparty/curl/urldata.h b/r5dev/thirdparty/curl/urldata.h index dae2e7ae..5ded3e0f 100644 --- a/r5dev/thirdparty/curl/urldata.h +++ b/r5dev/thirdparty/curl/urldata.h @@ -1320,7 +1320,10 @@ struct UrlState { /* buffers to store authentication data in, as parsed from input options */ struct timeval 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 */ + long padding; /* padding to keep structure compatible with apex legends, + the game uses this version of libcurl, and we hook in code + to solve any potential security bugs or server crashers */ char *headerbuff; /* allocated buffer to store headers in */ size_t headersize; /* size of the allocation */