diff options
author | cy <cy@FreeBSD.org> | 2015-05-04 04:45:59 +0000 |
---|---|---|
committer | cy <cy@FreeBSD.org> | 2015-05-04 04:45:59 +0000 |
commit | 1818eba70c74c4ba7173ef82fd98d197914adc74 (patch) | |
tree | 62ff96a32b854c652d9d65280d1d6fd2089b2f1e /contrib/ntp/ntpd/ntp_loopfilter.c | |
parent | 46cb5cb412522de16502b815c1126a1bf652045b (diff) | |
parent | f63afe28012870b3eb07e80844160966b32ef52e (diff) | |
download | FreeBSD-src-1818eba70c74c4ba7173ef82fd98d197914adc74.zip FreeBSD-src-1818eba70c74c4ba7173ef82fd98d197914adc74.tar.gz |
MFV ntp 4.2.8p2 (r281348)
Reviewed by: delphij (suggested MFC)
Approved by: roberto
Security: CVE-2015-1798, CVE-2015-1799
Security: VuXML ebd84c96-dd7e-11e4-854e-3c970e169bc2
MFC after: 1 month
Diffstat (limited to 'contrib/ntp/ntpd/ntp_loopfilter.c')
-rw-r--r-- | contrib/ntp/ntpd/ntp_loopfilter.c | 136 |
1 files changed, 96 insertions, 40 deletions
diff --git a/contrib/ntp/ntpd/ntp_loopfilter.c b/contrib/ntp/ntpd/ntp_loopfilter.c index 82ff163..e47f83b 100644 --- a/contrib/ntp/ntpd/ntp_loopfilter.c +++ b/contrib/ntp/ntpd/ntp_loopfilter.c @@ -46,7 +46,7 @@ #define CLOCK_LIMIT 30 /* poll-adjust threshold */ #define CLOCK_PGATE 4. /* poll-adjust gate */ #define PPS_MAXAGE 120 /* kernel pps signal timeout (s) */ -#define FREQTOD(x) ((x) / 65536e6) /* NTP to double */ +#define FREQTOD(x) ((x) / 65536e6) /* NTP to double */ #define DTOFREQ(x) ((int32)((x) * 65536e6)) /* double to NTP */ /* @@ -106,7 +106,8 @@ /* * Program variables that can be tinkered. */ -double clock_max = CLOCK_MAX; /* step threshold */ +double clock_max_back = CLOCK_MAX; /* step threshold */ +double clock_max_fwd = CLOCK_MAX; /* step threshold */ double clock_minstep = CLOCK_MINSTEP; /* stepout threshold */ double clock_panic = CLOCK_PANIC; /* panic threshold */ double clock_phi = CLOCK_PHI; /* dispersion rate (s/s) */ @@ -152,8 +153,10 @@ int kern_enable = TRUE; /* kernel support enabled */ int hardpps_enable; /* kernel PPS discipline enabled */ int ext_enable; /* external clock enabled */ int pps_stratum; /* pps stratum */ -int allow_panic = FALSE; /* allow panic correction */ -int mode_ntpdate = FALSE; /* exit on first clock set */ +int kernel_status; /* from ntp_adjtime */ +int allow_panic = FALSE; /* allow panic correction (-g) */ +int force_step_once = FALSE; /* always step time once at startup (-G) */ +int mode_ntpdate = FALSE; /* exit on first clock set (-q) */ int freq_cnt; /* initial frequency clamp */ int freq_set; /* initial set frequency switch */ @@ -279,47 +282,69 @@ ntp_adjtime_error_handler( } break; #ifdef TIME_OK - case TIME_OK: /* 0 no leap second warning */ - /* OK means OK */ + case TIME_OK: /* 0: synchronized, no leap second warning */ + /* msyslog(LOG_INFO, "kernel reports time is synchronized normally"); */ break; +#else +# warning TIME_OK is not defined #endif #ifdef TIME_INS - case TIME_INS: /* 1 positive leap second warning */ - msyslog(LOG_INFO, "%s: %s line %d: kernel reports positive leap second warning state", - caller, file_name(), line - ); + case TIME_INS: /* 1: positive leap second warning */ + msyslog(LOG_INFO, "kernel reports leap second insertion scheduled"); break; +#else +# warning TIME_INS is not defined #endif #ifdef TIME_DEL - case TIME_DEL: /* 2 negative leap second warning */ - msyslog(LOG_INFO, "%s: %s line %d: kernel reports negative leap second warning state", - caller, file_name(), line - ); + case TIME_DEL: /* 2: negative leap second warning */ + msyslog(LOG_INFO, "kernel reports leap second deletion scheduled"); break; +#else +# warning TIME_DEL is not defined #endif #ifdef TIME_OOP - case TIME_OOP: /* 3 leap second in progress */ - msyslog(LOG_INFO, "%s: %s line %d: kernel reports leap second in progress", - caller, file_name(), line - ); + case TIME_OOP: /* 3: leap second in progress */ + msyslog(LOG_INFO, "kernel reports leap second in progress"); break; +#else +# warning TIME_OOP is not defined #endif #ifdef TIME_WAIT - case TIME_WAIT: /* 4 leap second has occured */ - msyslog(LOG_INFO, "%s: %s line %d: kernel reports leap second has occured", - caller, file_name(), line - ); + case TIME_WAIT: /* 4: leap second has occured */ + msyslog(LOG_INFO, "kernel reports leap second has occurred"); break; +#else +# warning TIME_WAIT is not defined #endif #ifdef TIME_ERROR - case TIME_ERROR: /* loss of synchronization */ + case TIME_ERROR: /* 5: unsynchronized, or loss of synchronization */ + /* error (see status word) */ if (pps_call && !(ptimex->status & STA_PPSSIGNAL)) report_event(EVNT_KERN, NULL, "PPS no signal"); errno = saved_errno; DPRINTF(1, ("kernel loop status (%s) %d %m\n", k_st_flags(ptimex->status), errno)); + /* + * This code may be returned when ntp_adjtime() has just + * been called for the first time, quite a while after + * startup, when ntpd just starts to discipline the kernel + * time. In this case the occurrence of this message + * can be pretty confusing. + * + * HMS: How about a message when we begin kernel processing: + * Determining kernel clock state... + * so an initial TIME_ERROR message is less confising, + * or skipping the first message (ugh), + * or ??? + * msyslog(LOG_INFO, "kernel reports time synchronization lost"); + */ + errno = saved_errno; /* may not be needed */ + msyslog(LOG_INFO, "kernel reports TIME_ERROR: %#x: %s %m", + ptimex->status, k_st_flags(ptimex->status)); break; +#else +# warning TIME_ERROR is not defined #endif default: msyslog(LOG_NOTICE, "%s: %s line %d: unhandled return value %d from ntp_adjtime in %s at line %d", @@ -403,7 +428,8 @@ local_clock( * directly to the terminal. */ if (mode_ntpdate) { - if (fabs(fp_offset) > clock_max && clock_max > 0) { + if ( ( fp_offset > clock_max_fwd && clock_max_fwd > 0) + || (-fp_offset > clock_max_back && clock_max_back > 0)) { step_systime(fp_offset); msyslog(LOG_NOTICE, "ntpd: time set %+.6f s", fp_offset); @@ -452,10 +478,10 @@ local_clock( * threshold (128 ms) and when it does not. Under certain * conditions updates are suspended until the stepout theshold * (900 s) is exceeded. See the documentation on how these - * thresholds interact with commands and command line options. + * thresholds interact with commands and command line options. * * Note the kernel is disabled if step is disabled or greater - * than 0.5 s or in ntpdate mode. + * than 0.5 s or in ntpdate mode. */ osys_poll = sys_poll; if (sys_poll < peer->minpoll) @@ -465,7 +491,14 @@ local_clock( mu = current_time - clock_epoch; clock_frequency = drift_comp; rval = 1; - if (fabs(fp_offset) > clock_max && clock_max > 0) { + if ( ( fp_offset > clock_max_fwd && clock_max_fwd > 0) + || (-fp_offset > clock_max_back && clock_max_back > 0) + || force_step_once ) { + if (force_step_once) { + force_step_once = FALSE; /* we want this only once after startup */ + msyslog(LOG_NOTICE, "Doing intital time step" ); + } + switch (state) { /* @@ -525,7 +558,7 @@ local_clock( * threshold. Note that a single spike greater than the * step threshold is always suppressed, even with a * long time constant. - */ + */ default: snprintf(tbuf, sizeof(tbuf), "%+.6f s", fp_offset); @@ -543,7 +576,6 @@ local_clock( } rstclock(EVNT_SYNC, 0); } else { - /* * The offset is less than the step threshold. Calculate * the jitter as the exponentially weighted offset @@ -605,9 +637,9 @@ local_clock( /* * The PLL frequency gain (numerator) depends on * the minimum of the update interval and Allan - * intercept. This reduces the PLL gain when the + * intercept. This reduces the PLL gain when the * FLL becomes effective. - */ + */ etemp = min(ULOGTOD(allan_xpt), mu); dtemp = 4 * CLOCK_PLL * ULOGTOD(sys_poll); clock_frequency += fp_offset * etemp / (dtemp * @@ -706,8 +738,13 @@ local_clock( * the pps. In any case, fetch the kernel offset, * frequency and jitter. */ - if ((ntp_adj_ret = ntp_adjtime(&ntv)) != 0) { - ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, hardpps_enable, 0, __LINE__ - 1); + ntp_adj_ret = ntp_adjtime(&ntv); + /* + * A squeal is a return status < 0, or a state change. + */ + if ((0 > ntp_adj_ret) || (ntp_adj_ret != kernel_status)) { + kernel_status = ntp_adj_ret; + ntp_adjtime_error_handler(__func__, &ntv, ntp_adj_ret, errno, hardpps_enable, 0, __LINE__ - 1); } pll_status = ntv.status; #ifdef STA_NANO @@ -888,7 +925,7 @@ adj_host_clock( clock_offset -= offset_adj; /* * Windows port adj_systime() must be called each second, - * even if the argument is zero, to ease emulation of + * even if the argument is zero, to ease emulation of * adjtime() using Windows' slew API which controls the rate * but does not automatically stop slewing when an offset * has decayed to zero. @@ -917,7 +954,7 @@ rstclock( report_event(trans, NULL, NULL); state = trans; last_offset = clock_offset = offset; - clock_epoch = current_time; + clock_epoch = current_time; } @@ -1190,12 +1227,12 @@ loop_config( case LOOP_CODEC: /* audio codec frequency (codec) */ clock_codec = freq / 1e6; break; - + case LOOP_PHI: /* dispersion threshold (dispersion) */ clock_phi = freq / 1e6; break; - case LOOP_FREQ: /* initial frequency (freq) */ + case LOOP_FREQ: /* initial frequency (freq) */ init_drift_comp = freq; freq_set++; break; @@ -1216,8 +1253,27 @@ loop_config( break; case LOOP_MAX: /* step threshold (step) */ - clock_max = freq; - if (clock_max == 0 || clock_max > 0.5) + clock_max_fwd = clock_max_back = freq; + if (freq == 0 || freq > 0.5) + select_loop(FALSE); + break; + + case LOOP_MAX_BACK: /* step threshold (step) */ + clock_max_back = freq; + /* + * Leave using the kernel discipline code unless both + * limits are massive. This assumes the reason to stop + * using it is that it's pointless, not that it goes wrong. + */ + if ( (clock_max_back == 0 || clock_max_back > 0.5) + || (clock_max_fwd == 0 || clock_max_fwd > 0.5)) + select_loop(FALSE); + break; + + case LOOP_MAX_FWD: /* step threshold (step) */ + clock_max_fwd = freq; + if ( (clock_max_back == 0 || clock_max_back > 0.5) + || (clock_max_fwd == 0 || clock_max_fwd > 0.5)) select_loop(FALSE); break; @@ -1225,7 +1281,7 @@ loop_config( if (freq < CLOCK_MINSTEP) clock_minstep = CLOCK_MINSTEP; else - clock_minstep = freq; + clock_minstep = freq; break; case LOOP_TICK: /* tick increment (tick) */ |