conncache: fix multi-thread use of shared connection cache

It could accidentally let the connection get used by more than one
thread, leading to double-free and more.

Reported-by: Christopher Reid
Fixes #4544
Closes #4557
This commit is contained in:
Daniel Stenberg 2019-12-09 11:53:54 +01:00
parent 9e891ff54d
commit ee263de7a3
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
8 changed files with 58 additions and 52 deletions

View file

@ -1082,16 +1082,15 @@ ConnectionExists(struct Curl_easy *data,
check = curr->ptr;
curr = curr->next;
if(check->bits.connect_only)
/* connect-only connections will not be reused */
if(check->bits.connect_only || check->bits.close)
/* connect-only or to-be-closed connections will not be reused */
continue;
multiplexed = CONN_INUSE(check) &&
(bundle->multiuse == BUNDLE_MULTIPLEX);
if(canmultiplex) {
if(check->bits.protoconnstart && check->bits.close)
continue;
;
}
else {
if(multiplexed) {
@ -1111,12 +1110,9 @@ ConnectionExists(struct Curl_easy *data,
}
}
if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) ||
check->bits.close) {
if(!check->bits.close)
foundPendingCandidate = TRUE;
/* Don't pick a connection that hasn't connected yet or that is going
to get closed. */
if(check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) {
foundPendingCandidate = TRUE;
/* Don't pick a connection that hasn't connected yet */
infof(data, "Connection #%ld isn't open enough, can't reuse\n",
check->connection_id);
continue;
@ -1194,8 +1190,7 @@ ConnectionExists(struct Curl_easy *data,
already in use so we skip it */
continue;
if(CONN_INUSE(check) && check->data &&
(check->data->multi != needle->data->multi))
if(check->data && (check->data->multi != needle->data->multi))
/* this could be subject for multiplex use, but only if they belong to
* the same multi handle */
continue;
@ -1643,6 +1638,7 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
it may live on without (this specific) Curl_easy */
conn->fclosesocket = data->set.fclosesocket;
conn->closesocket_client = data->set.closesocket_client;
conn->lastused = Curl_now(); /* used now */
return conn;
error:
@ -3612,7 +3608,6 @@ static CURLcode create_conn(struct Curl_easy *data,
reuse = FALSE;
infof(data, "We can reuse, but we want a new connection anyway\n");
Curl_conncache_return_conn(conn_temp);
}
}
}