diff options
author | Thomas Markwalder <tmark@isc.org> | 2017-04-26 16:06:43 -0400 |
---|---|---|
committer | Thomas Markwalder <tmark@isc.org> | 2017-04-26 16:06:43 -0400 |
commit | 7ff65f8e1a7850731cb3517beb4dbb98f6608939 (patch) | |
tree | eda2cba6499faefd8418d0f7cbba7625ab712e61 | |
parent | 17296d25215cdad538f38af28744dd6f37dfd111 (diff) | |
download | isc-dhcp-7ff65f8e1a7850731cb3517beb4dbb98f6608939.tar.gz |
[v4_3] Capped large interval times to avoid fatal timer errors
Merged rt28038
-rw-r--r-- | RELNOTES | 6 | ||||
-rw-r--r-- | common/dispatch.c | 32 |
2 files changed, 24 insertions, 14 deletions
@@ -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)); |