Commit 2004eea2 authored by Thomas Markwalder's avatar Thomas Markwalder
Browse files

[master] Capped large interval times to avoid fatal timer errors

parent 86bda88b
...@@ -166,6 +166,11 @@ by Eric Young (eay@cryptsoft.com). ...@@ -166,6 +166,11 @@ by Eric Young (eay@cryptsoft.com).
for expiry in the script environment. for expiry in the script environment.
[ISC-Bugs #43326] [ISC-Bugs #43326]
- Common timer logic was modified to cap the maximum timeout values at
0x7FFFFFFF - 1. Values larger than that were causing fatal timer out of
range errors on 64-bit platforms. Thanks to Jiri Popelka at Red Hat for
reporting the issue.
[ISC-Bugs #28038]
Changes since 4.3.0 (bug fixes) Changes since 4.3.0 (bug fixes)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Network input dispatcher... */ Network input dispatcher... */
/* /*
* Copyright (c) 2004-2011,2013 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium * Copyright (c) 1995-2003 by Internet Software Consortium
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
...@@ -193,7 +193,6 @@ isclib_timer_callback(isc_task_t *taskp, ...@@ -193,7 +193,6 @@ isclib_timer_callback(isc_task_t *taskp,
/* maximum value for usec */ /* maximum value for usec */
#define USEC_MAX 1000000 #define USEC_MAX 1000000
#define DHCP_SEC_MAX 0xFFFFFFFF
void add_timeout (when, where, what, ref, unref) void add_timeout (when, where, what, ref, unref)
struct timeval *when; struct timeval *when;
...@@ -255,10 +254,14 @@ void add_timeout (when, where, what, ref, unref) ...@@ -255,10 +254,14 @@ void add_timeout (when, where, what, ref, unref)
* about the usec value, if it's zero we assume the caller didn't care. * about the usec value, if it's zero we assume the caller didn't care.
* *
* The ISC timer library doesn't seem to like negative values * The ISC timer library doesn't seem to like negative values
* and can't accept any values above 4G-1 seconds so we limit * and on 64-bit systems, isc_time_nowplusinterval() can generate range
* the values to 0 <= value < 4G-1. We do it before * errors on values sufficiently larger than 0x7FFFFFFF (TIME_MAX), so
* checking the trace option so that both the trace code and * we'll limit the interval to:
* the working code use the same values. *
* 0 <= interval <= TIME_MAX - 1
*
* We do it before checking the trace option so that both the trace
* code and * the working code use the same values.
*/ */
sec = when->tv_sec - cur_tv.tv_sec; sec = when->tv_sec - cur_tv.tv_sec;
...@@ -272,10 +275,11 @@ void add_timeout (when, where, what, ref, unref) ...@@ -272,10 +275,11 @@ void add_timeout (when, where, what, ref, unref)
if (sec < 0) { if (sec < 0) {
sec = 0; sec = 0;
usec = 0; usec = 0;
} else if (sec > DHCP_SEC_MAX) { } else if (sec >= TIME_MAX) {
log_error("Timeout requested too large " log_error("Timeout requested: %lu is too large, "
"reducing to 2^^32-1"); "reducing to: %lu (TIME_MAX - 1)", sec,
sec = DHCP_SEC_MAX; (unsigned long)(TIME_MAX - 1));
sec = TIME_MAX - 1;
usec = 0; usec = 0;
} else if (usec < 0) { } else if (usec < 0) {
usec = 0; usec = 0;
...@@ -288,7 +292,7 @@ void add_timeout (when, where, what, ref, unref) ...@@ -288,7 +292,7 @@ void add_timeout (when, where, what, ref, unref)
* here in case we want to compare timing information * here in case we want to compare timing information
* for some reason, like debugging. * for some reason, like debugging.
*/ */
q->when.tv_sec = cur_tv.tv_sec + (sec & DHCP_SEC_MAX); q->when.tv_sec = cur_tv.tv_sec + sec;
q->when.tv_usec = usec; q->when.tv_usec = usec;
#if defined (TRACING) #if defined (TRACING)
...@@ -339,12 +343,12 @@ void add_timeout (when, where, what, ref, unref) ...@@ -339,12 +343,12 @@ void add_timeout (when, where, what, ref, unref)
q->next = timeouts; q->next = timeouts;
timeouts = q; timeouts = q;
isc_interval_set(&interval, sec & DHCP_SEC_MAX, usec * 1000); isc_interval_set(&interval, sec, usec * 1000);
status = isc_time_nowplusinterval(&expires, &interval); status = isc_time_nowplusinterval(&expires, &interval);
if (status != ISC_R_SUCCESS) { if (status != ISC_R_SUCCESS) {
/* /*
* The system time function isn't happy or returned * The system time function isn't happy. Range errors
* a value larger than isc_time_t can hold. * should not be possible with the check logic above.
*/ */
log_fatal("Unable to set up timer: %s", log_fatal("Unable to set up timer: %s",
isc_result_totext(status)); isc_result_totext(status));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment