1
0
mirror of https://github.com/moparisthebest/curl synced 2024-11-14 21:45:13 -05:00

connection_check: restore original conn->data after the check

- Save the original conn->data before it's changed to the specified
  data transfer for the connection check and then restore it afterwards.

This is a follow-up to 38d8e1b 2019-02-11.

History:

It was discovered a month ago that before checking whether to extract a
dead connection that that connection should be associated with a "live"
transfer for the check (ie original conn->data ignored and set to the
passed in data). A fix was landed in 54b201b which did that and also
cleared conn->data after the check. The original conn->data was not
restored, so presumably it was thought that a valid conn->data was no
longer needed.

Several days later it was discovered that a valid conn->data was needed
after the check and follow-up fix was landed in bbae24c which partially
reverted the original fix and attempted to limit the scope of when
conn->data was changed to only when pruning dead connections. In that
case conn->data was not cleared and the original conn->data not
restored.

A month later it was discovered that the original fix was somewhat
correct; a "live" transfer is needed for the check in all cases
because original conn->data could be null which could cause a bad deref
at arbitrary points in the check. A fix was landed in 38d8e1b which
expanded the scope to all cases. conn->data was not cleared and the
original conn->data not restored.

A day later it was discovered that not restoring the original conn->data
may lead to busy loops in applications that use the event interface, and
given this observation it's a pretty safe assumption that there is some
code path that still needs the original conn->data. This commit is the
follow-up fix for that, it restores the original conn->data after the
connection check.

Assisted-by: tholin@users.noreply.github.com
Reported-by: tholin@users.noreply.github.com

Fixes https://github.com/curl/curl/issues/3542
Closes #3559
This commit is contained in:
Jay Satiro 2019-02-11 23:00:00 -05:00 committed by Daniel Stenberg
parent 49d73d40f6
commit 4015fae044
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -964,8 +964,10 @@ static bool extract_if_dead(struct connectdata *conn,
/* The protocol has a special method for checking the state of the /* The protocol has a special method for checking the state of the
connection. Use it to check if the connection is dead. */ connection. Use it to check if the connection is dead. */
unsigned int state; unsigned int state;
struct Curl_easy *olddata = conn->data;
conn->data = data; /* use this transfer for now */ conn->data = data; /* use this transfer for now */
state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD); state = conn->handler->connection_check(conn, CONNCHECK_ISDEAD);
conn->data = olddata;
dead = (state & CONNRESULT_DEAD); dead = (state & CONNRESULT_DEAD);
} }
else { else {
@ -994,7 +996,6 @@ struct prunedead {
static int call_extract_if_dead(struct connectdata *conn, void *param) static int call_extract_if_dead(struct connectdata *conn, void *param)
{ {
struct prunedead *p = (struct prunedead *)param; struct prunedead *p = (struct prunedead *)param;
conn->data = p->data; /* transfer to use for this check */
if(extract_if_dead(conn, p->data)) { if(extract_if_dead(conn, p->data)) {
/* stop the iteration here, pass back the connection that was extracted */ /* stop the iteration here, pass back the connection that was extracted */
p->extracted = conn; p->extracted = conn;