mirror of
https://github.com/moparisthebest/curl
synced 2025-03-01 09:51:46 -05:00
Curl_pgrsTime - return new time to avoid timeout integer overflow
Setting a timeout to INT_MAX could cause an immediate error to get returned as timeout because of an overflow when different values of 'now' were used. This is primarily fixed by having Curl_pgrsTime() return the "now" when TIMER_STARTSINGLE is set so that the parent function will continue using that time. Reported-by: Ionuț-Francisc Oancea Fixes #5583 Closes #5847
This commit is contained in:
parent
68a5132474
commit
a2c85bb8e4
@ -1317,10 +1317,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
|||||||
const struct Curl_dns_entry *remotehost)
|
const struct Curl_dns_entry *remotehost)
|
||||||
{
|
{
|
||||||
struct Curl_easy *data = conn->data;
|
struct Curl_easy *data = conn->data;
|
||||||
struct curltime before = Curl_now();
|
|
||||||
CURLcode result = CURLE_COULDNT_CONNECT;
|
CURLcode result = CURLE_COULDNT_CONNECT;
|
||||||
int i;
|
int i;
|
||||||
timediff_t timeout_ms = Curl_timeleft(data, &before, TRUE);
|
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||||
|
|
||||||
if(timeout_ms < 0) {
|
if(timeout_ms < 0) {
|
||||||
/* a precaution, no need to continue if time already is up */
|
/* a precaution, no need to continue if time already is up */
|
||||||
|
34
lib/multi.c
34
lib/multi.c
@ -1702,7 +1702,7 @@ CURLcode Curl_preconnect(struct Curl_easy *data)
|
|||||||
|
|
||||||
|
|
||||||
static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||||
struct curltime now,
|
struct curltime *nowp,
|
||||||
struct Curl_easy *data)
|
struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct Curl_message *msg = NULL;
|
struct Curl_message *msg = NULL;
|
||||||
@ -1743,7 +1743,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
(data->mstate < CURLM_STATE_COMPLETED)) {
|
(data->mstate < CURLM_STATE_COMPLETED)) {
|
||||||
/* we need to wait for the connect state as only then is the start time
|
/* we need to wait for the connect state as only then is the start time
|
||||||
stored, but we must not check already completed handles */
|
stored, but we must not check already completed handles */
|
||||||
timeout_ms = Curl_timeleft(data, &now,
|
timeout_ms = Curl_timeleft(data, nowp,
|
||||||
(data->mstate <= CURLM_STATE_DO)?
|
(data->mstate <= CURLM_STATE_DO)?
|
||||||
TRUE:FALSE);
|
TRUE:FALSE);
|
||||||
|
|
||||||
@ -1752,25 +1752,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
if(data->mstate == CURLM_STATE_WAITRESOLVE)
|
if(data->mstate == CURLM_STATE_WAITRESOLVE)
|
||||||
failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
|
failf(data, "Resolving timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||||
" milliseconds",
|
" milliseconds",
|
||||||
Curl_timediff(now, data->progress.t_startsingle));
|
Curl_timediff(*nowp, data->progress.t_startsingle));
|
||||||
else if(data->mstate == CURLM_STATE_WAITCONNECT)
|
else if(data->mstate == CURLM_STATE_WAITCONNECT)
|
||||||
failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
|
failf(data, "Connection timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||||
" milliseconds",
|
" milliseconds",
|
||||||
Curl_timediff(now, data->progress.t_startsingle));
|
Curl_timediff(*nowp, data->progress.t_startsingle));
|
||||||
else {
|
else {
|
||||||
struct SingleRequest *k = &data->req;
|
struct SingleRequest *k = &data->req;
|
||||||
if(k->size != -1) {
|
if(k->size != -1) {
|
||||||
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||||
" milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
|
" milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %"
|
||||||
CURL_FORMAT_CURL_OFF_T " bytes received",
|
CURL_FORMAT_CURL_OFF_T " bytes received",
|
||||||
Curl_timediff(now, data->progress.t_startsingle),
|
Curl_timediff(*nowp, data->progress.t_startsingle),
|
||||||
k->bytecount, k->size);
|
k->bytecount, k->size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T
|
||||||
" milliseconds with %" CURL_FORMAT_CURL_OFF_T
|
" milliseconds with %" CURL_FORMAT_CURL_OFF_T
|
||||||
" bytes received",
|
" bytes received",
|
||||||
Curl_timediff(now, data->progress.t_startsingle),
|
Curl_timediff(*nowp, data->progress.t_startsingle),
|
||||||
k->bytecount);
|
k->bytecount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1795,7 +1795,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
if(!result) {
|
if(!result) {
|
||||||
/* after init, go CONNECT */
|
/* after init, go CONNECT */
|
||||||
multistate(data, CURLM_STATE_CONNECT);
|
multistate(data, CURLM_STATE_CONNECT);
|
||||||
Curl_pgrsTime(data, TIMER_STARTOP);
|
*nowp = Curl_pgrsTime(data, TIMER_STARTOP);
|
||||||
rc = CURLM_CALL_MULTI_PERFORM;
|
rc = CURLM_CALL_MULTI_PERFORM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1812,7 +1812,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
if(result)
|
if(result)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
*nowp = Curl_pgrsTime(data, TIMER_STARTSINGLE);
|
||||||
if(data->set.timeout)
|
if(data->set.timeout)
|
||||||
Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
|
Curl_expire(data, data->set.timeout, EXPIRE_TIMEOUT);
|
||||||
|
|
||||||
@ -2220,7 +2220,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
if(Curl_pgrsUpdate(data->conn))
|
if(Curl_pgrsUpdate(data->conn))
|
||||||
result = CURLE_ABORTED_BY_CALLBACK;
|
result = CURLE_ABORTED_BY_CALLBACK;
|
||||||
else
|
else
|
||||||
result = Curl_speedcheck(data, now);
|
result = Curl_speedcheck(data, *nowp);
|
||||||
|
|
||||||
if(!result) {
|
if(!result) {
|
||||||
send_timeout_ms = 0;
|
send_timeout_ms = 0;
|
||||||
@ -2230,7 +2230,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
data->progress.ul_limit_size,
|
data->progress.ul_limit_size,
|
||||||
data->set.max_send_speed,
|
data->set.max_send_speed,
|
||||||
data->progress.ul_limit_start,
|
data->progress.ul_limit_start,
|
||||||
now);
|
*nowp);
|
||||||
|
|
||||||
recv_timeout_ms = 0;
|
recv_timeout_ms = 0;
|
||||||
if(data->set.max_recv_speed > 0)
|
if(data->set.max_recv_speed > 0)
|
||||||
@ -2239,11 +2239,11 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
data->progress.dl_limit_size,
|
data->progress.dl_limit_size,
|
||||||
data->set.max_recv_speed,
|
data->set.max_recv_speed,
|
||||||
data->progress.dl_limit_start,
|
data->progress.dl_limit_start,
|
||||||
now);
|
*nowp);
|
||||||
|
|
||||||
if(!send_timeout_ms && !recv_timeout_ms) {
|
if(!send_timeout_ms && !recv_timeout_ms) {
|
||||||
multistate(data, CURLM_STATE_PERFORM);
|
multistate(data, CURLM_STATE_PERFORM);
|
||||||
Curl_ratelimit(data, now);
|
Curl_ratelimit(data, *nowp);
|
||||||
}
|
}
|
||||||
else if(send_timeout_ms >= recv_timeout_ms)
|
else if(send_timeout_ms >= recv_timeout_ms)
|
||||||
Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
|
Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
|
||||||
@ -2265,7 +2265,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
data->progress.ul_limit_size,
|
data->progress.ul_limit_size,
|
||||||
data->set.max_send_speed,
|
data->set.max_send_speed,
|
||||||
data->progress.ul_limit_start,
|
data->progress.ul_limit_start,
|
||||||
now);
|
*nowp);
|
||||||
|
|
||||||
/* check if over recv speed */
|
/* check if over recv speed */
|
||||||
recv_timeout_ms = 0;
|
recv_timeout_ms = 0;
|
||||||
@ -2274,10 +2274,10 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
data->progress.dl_limit_size,
|
data->progress.dl_limit_size,
|
||||||
data->set.max_recv_speed,
|
data->set.max_recv_speed,
|
||||||
data->progress.dl_limit_start,
|
data->progress.dl_limit_start,
|
||||||
now);
|
*nowp);
|
||||||
|
|
||||||
if(send_timeout_ms || recv_timeout_ms) {
|
if(send_timeout_ms || recv_timeout_ms) {
|
||||||
Curl_ratelimit(data, now);
|
Curl_ratelimit(data, *nowp);
|
||||||
multistate(data, CURLM_STATE_TOOFAST);
|
multistate(data, CURLM_STATE_TOOFAST);
|
||||||
if(send_timeout_ms >= recv_timeout_ms)
|
if(send_timeout_ms >= recv_timeout_ms)
|
||||||
Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
|
Curl_expire(data, send_timeout_ms, EXPIRE_TOOFAST);
|
||||||
@ -2557,7 +2557,7 @@ CURLMcode curl_multi_perform(struct Curl_multi *multi, int *running_handles)
|
|||||||
SIGPIPE_VARIABLE(pipe_st);
|
SIGPIPE_VARIABLE(pipe_st);
|
||||||
|
|
||||||
sigpipe_ignore(data, &pipe_st);
|
sigpipe_ignore(data, &pipe_st);
|
||||||
result = multi_runsingle(multi, now, data);
|
result = multi_runsingle(multi, &now, data);
|
||||||
sigpipe_restore(&pipe_st);
|
sigpipe_restore(&pipe_st);
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
@ -3031,7 +3031,7 @@ static CURLMcode multi_socket(struct Curl_multi *multi,
|
|||||||
SIGPIPE_VARIABLE(pipe_st);
|
SIGPIPE_VARIABLE(pipe_st);
|
||||||
|
|
||||||
sigpipe_ignore(data, &pipe_st);
|
sigpipe_ignore(data, &pipe_st);
|
||||||
result = multi_runsingle(multi, now, data);
|
result = multi_runsingle(multi, &now, data);
|
||||||
sigpipe_restore(&pipe_st);
|
sigpipe_restore(&pipe_st);
|
||||||
|
|
||||||
if(CURLM_OK >= result) {
|
if(CURLM_OK >= result) {
|
||||||
|
@ -164,9 +164,13 @@ void Curl_pgrsResetTransferSizes(struct Curl_easy *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
*
|
||||||
|
* Curl_pgrsTime(). Store the current time at the given label. This fetches a
|
||||||
|
* fresh "now" and returns it.
|
||||||
|
*
|
||||||
* @unittest: 1399
|
* @unittest: 1399
|
||||||
*/
|
*/
|
||||||
void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
||||||
{
|
{
|
||||||
struct curltime now = Curl_now();
|
struct curltime now = Curl_now();
|
||||||
timediff_t *delta = NULL;
|
timediff_t *delta = NULL;
|
||||||
@ -209,7 +213,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
|||||||
* changing the t_starttransfer time.
|
* changing the t_starttransfer time.
|
||||||
*/
|
*/
|
||||||
if(data->progress.is_t_startransfer_set) {
|
if(data->progress.is_t_startransfer_set) {
|
||||||
return;
|
return now;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
data->progress.is_t_startransfer_set = true;
|
data->progress.is_t_startransfer_set = true;
|
||||||
@ -228,6 +232,7 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
|||||||
us = 1; /* make sure at least one microsecond passed */
|
us = 1; /* make sure at least one microsecond passed */
|
||||||
*delta += us;
|
*delta += us;
|
||||||
}
|
}
|
||||||
|
return now;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curl_pgrsStartNow(struct Curl_easy *data)
|
void Curl_pgrsStartNow(struct Curl_easy *data)
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -49,7 +49,7 @@ void Curl_pgrsSetUploadCounter(struct Curl_easy *data, curl_off_t size);
|
|||||||
void Curl_ratelimit(struct Curl_easy *data, struct curltime now);
|
void Curl_ratelimit(struct Curl_easy *data, struct curltime now);
|
||||||
int Curl_pgrsUpdate(struct connectdata *);
|
int Curl_pgrsUpdate(struct connectdata *);
|
||||||
void Curl_pgrsResetTransferSizes(struct Curl_easy *data);
|
void Curl_pgrsResetTransferSizes(struct Curl_easy *data);
|
||||||
void Curl_pgrsTime(struct Curl_easy *data, timerid timer);
|
struct curltime Curl_pgrsTime(struct Curl_easy *data, timerid timer);
|
||||||
timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
|
timediff_t Curl_pgrsLimitWaitTime(curl_off_t cursize,
|
||||||
curl_off_t startsize,
|
curl_off_t startsize,
|
||||||
curl_off_t limit,
|
curl_off_t limit,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user