summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2017-04-26 16:06:43 -0400
committerThomas Markwalder <tmark@isc.org>2017-04-26 16:06:43 -0400
commit7ff65f8e1a7850731cb3517beb4dbb98f6608939 (patch)
treeeda2cba6499faefd8418d0f7cbba7625ab712e61
parent17296d25215cdad538f38af28744dd6f37dfd111 (diff)
downloadisc-dhcp-7ff65f8e1a7850731cb3517beb4dbb98f6608939.tar.gz
[v4_3] Capped large interval times to avoid fatal timer errors
Merged rt28038
-rw-r--r--RELNOTES6
-rw-r--r--common/dispatch.c32
2 files changed, 24 insertions, 14 deletions
diff --git a/RELNOTES b/RELNOTES
index 1a7cc019..db6c1e36 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -101,6 +101,12 @@ 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.5b1
- Corrected a bug which could cause the server to sporadically crash while
diff --git a/common/dispatch.c b/common/dispatch.c
index c75a003b..b16f1eb7 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 too large "
+ "reducing to: %lu (TIME_MAX - 1)",
+ (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));