diff options
author | Thomas Markwalder <tmark@isc.org> | 2017-04-26 15:26:17 -0400 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2017-04-26 15:26:17 -0400 |
commit | 2004eea2492edfdc3d38bca2b534254169e770bb (patch) | |
tree | 31482ac6eb10b9f1b133d16bd461f353542aa22d | |
parent | 86bda88b2e59347da621e4507787e9392c9bc773 (diff) | |
download | isc-dhcp-2004eea2492edfdc3d38bca2b534254169e770bb.tar.gz |
[master] Capped large interval times to avoid fatal timer errors
-rw-r--r-- | RELNOTES | 5 | ||||
-rw-r--r-- | common/dispatch.c | 32 |
2 files changed, 23 insertions, 14 deletions
@@ -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)); |