summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2017-04-26 15:26:17 -0400
committerThomas Markwalder <tmark@isc.org>2017-04-26 15:26:17 -0400
commit2004eea2492edfdc3d38bca2b534254169e770bb (patch)
tree31482ac6eb10b9f1b133d16bd461f353542aa22d
parent86bda88b2e59347da621e4507787e9392c9bc773 (diff)
downloadisc-dhcp-2004eea2492edfdc3d38bca2b534254169e770bb.tar.gz
[master] Capped large interval times to avoid fatal timer errors
-rw-r--r--RELNOTES5
-rw-r--r--common/dispatch.c32
2 files changed, 23 insertions, 14 deletions
diff --git a/RELNOTES b/RELNOTES
index a6c96f8d..12f34481 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -166,6 +166,11 @@ by Eric Young (eay@cryptsoft.com).
for expiry in the script environment.
[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)
diff --git a/common/dispatch.c b/common/dispatch.c
index c75a003b..3ca3749b 100644
--- a/common/dispatch.c
+++ b/common/dispatch.c
@@ -3,7 +3,7 @@
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
*
* Permission to use, copy, modify, and distribute this software for any
@@ -193,7 +193,6 @@ isclib_timer_callback(isc_task_t *taskp,
/* maximum value for usec */
#define USEC_MAX 1000000
-#define DHCP_SEC_MAX 0xFFFFFFFF
void add_timeout (when, where, what, ref, unref)
struct timeval *when;
@@ -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.
*
* The ISC timer library doesn't seem to like negative values
- * and can't accept any values above 4G-1 seconds so we limit
- * the values to 0 <= value < 4G-1. We do it before
- * checking the trace option so that both the trace code and
- * the working code use the same values.
+ * and on 64-bit systems, isc_time_nowplusinterval() can generate range
+ * errors on values sufficiently larger than 0x7FFFFFFF (TIME_MAX), so
+ * we'll limit the interval to:
+ *
+ * 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;
@@ -272,10 +275,11 @@ void add_timeout (when, where, what, ref, unref)
if (sec < 0) {
sec = 0;
usec = 0;
- } else if (sec > DHCP_SEC_MAX) {
- log_error("Timeout requested too large "
- "reducing to 2^^32-1");
- sec = DHCP_SEC_MAX;
+ } else if (sec >= TIME_MAX) {
+ log_error("Timeout requested: %lu is too large, "
+ "reducing to: %lu (TIME_MAX - 1)", sec,
+ (unsigned long)(TIME_MAX - 1));
+ sec = TIME_MAX - 1;
usec = 0;
} else if (usec < 0) {
usec = 0;
@@ -288,7 +292,7 @@ void add_timeout (when, where, what, ref, unref)
* here in case we want to compare timing information
* 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;
#if defined (TRACING)
@@ -339,12 +343,12 @@ void add_timeout (when, where, what, ref, unref)
q->next = timeouts;
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);
if (status != ISC_R_SUCCESS) {
/*
- * The system time function isn't happy or returned
- * a value larger than isc_time_t can hold.
+ * The system time function isn't happy. Range errors
+ * should not be possible with the check logic above.
*/
log_fatal("Unable to set up timer: %s",
isc_result_totext(status));