From: Dave Hart Date: Wed, 18 Apr 2012 11:46:26 +0000 (+0000) Subject: [Bug 2141] handle_sigio() calls get_systime(), which must be X-Git-Tag: NTP_4_2_7P273~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ee3c3f7bfebdce5751b4b8c176e7f51e0589cf71;p=thirdparty%2Fntp.git [Bug 2141] handle_sigio() calls get_systime(), which must be reentrant when SIGIO is used. Sanity checks relative to the prior get_systime() are disabled in ntpd on systems with signaled I/O, but active in sntp and ntpdate. bk: 4f8ea992tqrAYsnppvU0M7KdOzxwUw --- diff --git a/ChangeLog b/ChangeLog index d1d7df308..5083b6e78 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +* [Bug 2141] handle_sigio() calls get_systime(), which must be + reentrant when SIGIO is used. Sanity checks relative to the prior + get_systime() are disabled in ntpd on systems with signaled I/O, but + active in sntp and ntpdate. (4.2.7p272) 2012/04/14 Released by Harlan Stenn * LCRYPTO is gone - replace with VER_SUFFIX. * Change the link order for ntpsntpd. diff --git a/include/iosignal.h b/include/iosignal.h index 632ae7e02..02d589923 100644 --- a/include/iosignal.h +++ b/include/iosignal.h @@ -33,6 +33,10 @@ # endif /* SIGIO == SIGPOLL */ # endif /* USE_SIGIO && USE_SIGPOLL */ +#define USING_SIGIO() using_sigio + +extern int using_sigio; + extern void block_sigio (void); extern void unblock_sigio (void); extern int init_clock_sig (struct refclockio *); @@ -46,6 +50,7 @@ RETSIGTYPE sigio_handler (int); #else /* !HAVE_SIGNALED_IO follows */ # define BLOCKIO() do {} while (0) # define UNBLOCKIO() do {} while (0) +# define USING_SIGIO() FALSE #endif #endif /* IOSIGNAL_H */ diff --git a/libntp/iosignal.c b/libntp/iosignal.c index b10a161e9..0176d8cbe 100644 --- a/libntp/iosignal.c +++ b/libntp/iosignal.c @@ -311,6 +311,7 @@ sigio_handler( void set_signal(void) { + using_sigio = TRUE; # ifdef USE_SIGIO (void) signal_no_reset(SIGIO, sigio_handler); # endif @@ -481,6 +482,7 @@ block_sigio(void) void set_signal(void) { + using_sigio = TRUE; (void) signal_no_reset(SIGIO, sigio_handler); } diff --git a/libntp/systime.c b/libntp/systime.c index b98bb7258..5264b9e12 100644 --- a/libntp/systime.c +++ b/libntp/systime.c @@ -10,6 +10,7 @@ #include "ntp_syslog.h" #include "ntp_stdlib.h" #include "ntp_random.h" +#include "iosignal.h" #include "timevalops.h" #include "timespecops.h" #include "ntp_calendar.h" @@ -84,6 +85,11 @@ static int systime_init_done; #else # define DONE_SYSTIME_INIT() do {} while (FALSE) #endif + +#ifdef HAVE_SIGNALED_IO +int using_sigio; +#endif + #ifdef SYS_WINNT CRITICAL_SECTION get_systime_cs; #endif @@ -176,20 +182,29 @@ get_systime( * fuzzed result is strictly later than the prior. Limit the * necessary fiction to 1 second. */ - ts_min = add_tspec_ns(ts_prev, sys_fuzz_nsec); - if (cmp_tspec(ts, ts_min) < 0) { - ts_lam = sub_tspec(ts_min, ts); - if (ts_lam.tv_sec > 0 && !lamport_violated) { - msyslog(LOG_ERR, - "get_systime Lamport advance exceeds one second (%.9f)", - ts_lam.tv_sec + 1e-9 * ts_lam.tv_nsec); - exit(1); + if (!USING_SIGIO()) { + ts_min = add_tspec_ns(ts_prev, sys_fuzz_nsec); + if (cmp_tspec(ts, ts_min) < 0) { + ts_lam = sub_tspec(ts_min, ts); + if (ts_lam.tv_sec > 0 && !lamport_violated) { + msyslog(LOG_ERR, + "get_systime Lamport advance exceeds one second (%.9f)", + ts_lam.tv_sec + + 1e-9 * ts_lam.tv_nsec); + exit(1); + } + if (!lamport_violated) + ts = ts_min; } - if (!lamport_violated) - ts = ts_min; + ts_prev_log = ts_prev; + ts_prev = ts; + } else { + /* + * Quiet "ts_prev_log.tv_sec may be used uninitialized" + * warning from x86 gcc 4.5.2. + */ + ZERO(ts_prev_log); } - ts_prev_log = ts_prev; - ts_prev = ts; /* convert from timespec to l_fp fixed-point */ result = tspec_stamp_to_lfp(ts); @@ -206,27 +221,32 @@ get_systime( * sys_residual's effect for now) once sys_fuzz has been * determined. */ - if (!L_ISZERO(&lfp_prev) && !lamport_violated) { - if (!L_ISGTU(&result, &lfp_prev) && sys_fuzz > 0.) { - msyslog(LOG_ERR, "ts_min %s ts_prev %s ts %s", - tspectoa(ts_min), tspectoa(ts_prev_log), - tspectoa(ts)); - msyslog(LOG_ERR, "sys_fuzz %ld nsec, this fuzz %.9f, prior %.9f", - sys_fuzz_nsec, dfuzz, dfuzz_prev); - lfpdelta = lfp_prev; - L_SUB(&lfpdelta, &result); - LFPTOD(&lfpdelta, ddelta); - msyslog(LOG_ERR, - "get_systime prev result 0x%x.%08x is %.9f later than 0x%x.%08x", - lfp_prev.l_ui, lfp_prev.l_uf, - ddelta, result.l_ui, result.l_uf); + if (!USING_SIGIO()) { + if (!L_ISZERO(&lfp_prev) && !lamport_violated) { + if (!L_ISGTU(&result, &lfp_prev) && + sys_fuzz > 0.) { + msyslog(LOG_ERR, "ts_prev %s ts_min %s", + tspectoa(ts_prev_log), + tspectoa(ts_min)); + msyslog(LOG_ERR, "ts %s", tspectoa(ts)); + msyslog(LOG_ERR, "sys_fuzz %ld nsec, prior fuzz %.9f", + sys_fuzz_nsec, dfuzz_prev); + msyslog(LOG_ERR, "this fuzz %.9f", + dfuzz); + lfpdelta = lfp_prev; + L_SUB(&lfpdelta, &result); + LFPTOD(&lfpdelta, ddelta); + msyslog(LOG_ERR, + "prev get_systime 0x%x.%08x is %.9f later than 0x%x.%08x", + lfp_prev.l_ui, lfp_prev.l_uf, + ddelta, result.l_ui, result.l_uf); + } } + lfp_prev = result; + dfuzz_prev = dfuzz; + if (lamport_violated) + lamport_violated = FALSE; } - lfp_prev = result; - dfuzz_prev = dfuzz; - if (lamport_violated) - lamport_violated = FALSE; - LEAVE_GET_SYSTIME_CRITSEC(); *now = result; }