Package: ntp
Version: 1:4.2.6.p5+dfsg-7

I'd like to report a bug about inserting the leap second.
It seems not be fixed yet in most Debian versions.
Also, I attached a patch for the bug, and test results of the patch.
Please see [Patches] and [Testing] for more details.

[Bug]

ntpd inserts a leap second even though the step threshold is larger than 1s.

This bug appears only when the step threshold is larger than 1s and
the kernel discipline is disabled. For example, ntpd inserts a leap second
even when it's running with "-x" option.
("-x": the step threshold is set to 600s and kernel discipline is disabled)

Please note that Linux kernel is not related to this bug.

[NTP versions]

This bug is included in all ntp packages that is based on 4.2.6.
  squeeze-lts 4.2.6.p2+dfsg-1+deb6u3
  wheezy      4.2.6.p5+dfsg-2+deb7u4
  jessie      4.2.6.p5+dfsg-7
  stretch     4.2.6.p5+dfsg-7

Only sid seems not to include the bug because its ntp version is 4.2.8 based,
which includes the upstream bug fix. [0]

[Effects of the bug]

Applications that assume the system clock is never "stepped" might be crashed.

[Patches]

RedHat provides patches ("ntp-4.2.6p5-xleap.patch") to fix this bug. [1]
In the following ntp version, the bug seems to be fixed by the patch.
  RHEL7 ntp-4.2.6p5-19.el7 [2]
  RHEL6 ntp-4.2.6p5-2.el6_6 [3]

The above two patches ([2] & [3]) are little different.
I prefer the patch for RHEL7 [2] because it includes logging about the leap 
second.

I created a patch for Debian ("xleap.patch") based on [2].
Could you consider adding this patch into 4.2.6 based ntp packages?
I already confirmed that xleap.patch can be applied to the both of squeeze-lts 
and jessie.

[Testing]

I already reproduced the bug and confirmed that ntpd (NTP client) that
xleap.patch is applied works correctly on Debian squeeze-lts and jessie 
environment.

I used a simple SNTP server script [4] to check the behavior of ntpd.
The SNTP server [4] can send NTP packets that LI (Leap Indicator) bit is set.
I attached the test results:

        | Reproduce the bug             | Test the patched ntpd
--------+-------------------------------+---------------------------
squeeze | squeeze-lts_without-patch.txt | squeeze-lts_with-patch.txt
jessie  | jessie_without-patch.txt      | jessie_with-patch.txt


[0] http://bk1.ntp.org/ntp-stable/?PAGE=patch&REV=5536a01bsP24qMk41nIZEUlK9FTYJw
[1] https://access.redhat.com/solutions/1379783
[2] https://rhn.redhat.com/errata/RHBA-2015-1159.html
[3] https://rhn.redhat.com/errata/RHBA-2015-0690.html
[4] http://www2.nict.go.jp/aeri/sts/tsp/link/leap.html#2

diff -ur ntp-4.2.6.p2+dfsg.orig//html/miscopt.html ntp-4.2.6.p2+dfsg/html/miscopt.html
--- ntp-4.2.6.p2+dfsg.orig//html/miscopt.html	2010-07-14 03:14:18.000000000 +0900
+++ ntp-4.2.6.p2+dfsg/html/miscopt.html	2015-07-28 22:31:33.642183713 +0900
@@ -88,7 +88,7 @@
 						is 0.128 s. If set to zero, step adjustments will never
 						occur. Note: The kernel time discipline is disabled if
 						the step threshold is set to zero or greater than 0.5
-						s.</dd>
+						s and the threshold is applied also to leap second corrections.</dd>
 					<dt><tt>stepout <i>stepout</i></tt></dt>
 					<dd>Specifies the stepout threshold in seconds. The default without this
 						command is 900 s.  If set to zero, popcorn spikes will
diff -ur ntp-4.2.6.p2+dfsg.orig//html/ntpd.html ntp-4.2.6.p2+dfsg/html/ntpd.html
--- ntp-4.2.6.p2+dfsg.orig//html/ntpd.html	2010-07-14 03:14:18.000000000 +0900
+++ ntp-4.2.6.p2+dfsg/html/ntpd.html	2015-07-28 22:31:33.642183713 +0900
@@ -142,7 +142,7 @@
 			<dt><tt>-V <i>variable</i></tt></dt>
 			<dd>Add a system variable listed by default.</dd>
 			<dt><tt>-x</tt></dt>
-			<dd>Normally, the time is slewed if the offset is less than the step threshold, which is 128 ms by default, and stepped if above the threshold. This option sets the threshold to 600 s, which is well within the accuracy window to set the clock manually. Note: Since the slew rate of typical Unix kernels is limited to 0.5 ms/s, each second of adjustment requires an amortization interval of 2000 s. Thus, an adjustment as much as 600 s will take almost 14 days to complete. This option can be used with the <tt>-g</tt> and <tt>-q</tt> options. See the <tt>tinker</tt> command for other options. Note: The kernel time discipline is disabled with this option.</dd>
+			<dd>Normally, the time is slewed if the offset is less than the step threshold, which is 128 ms by default, and stepped if above the threshold. This option sets the threshold to 600 s, which is well within the accuracy window to set the clock manually. Note: Since the slew rate of typical Unix kernels is limited to 0.5 ms/s, each second of adjustment requires an amortization interval of 2000 s. Thus, an adjustment as much as 600 s will take almost 14 days to complete. This option can be used with the <tt>-g</tt> and <tt>-q</tt> options. See the <tt>tinker</tt> command for other options. Note: The kernel time discipline is disabled with this option and the step threshold is applied also to leap second corrections.</dd>
 			<dt><tt>--pccfreq <i>frequency</i></tt></dt>
 			<dd>Substitute processor cycle counter for QueryPerformanceCounter unconditionally
 				using the given frequency (in Hz). <tt>--pccfreq</tt> can be used on systems
diff -ur ntp-4.2.6.p2+dfsg.orig//ntpd/ntp_timer.c ntp-4.2.6.p2+dfsg/ntpd/ntp_timer.c
--- ntp-4.2.6.p2+dfsg.orig//ntpd/ntp_timer.c	2010-07-14 03:14:18.000000000 +0900
+++ ntp-4.2.6.p2+dfsg/ntpd/ntp_timer.c	2015-07-28 22:31:33.642183713 +0900
@@ -338,8 +338,14 @@
 			sys_leap = LEAP_NOWARNING;
 			sys_tai = leap_tai;
 #ifdef KERNEL_PLL
-			if (!(pll_control && kern_enable))
-				step_systime(-1.0);
+			if (!pll_control || !kern_enable) {
+				if (clock_max < 1.0 && clock_max > 0.0) {
+					step_systime(-1.0);
+					msyslog(LOG_NOTICE, "Inserting positive leap second");
+				} else {
+					msyslog(LOG_NOTICE, "Ignoring leap second");
+				}
+			}
 #else /* KERNEL_PLL */
 #ifndef SYS_WINNT /* WinNT port has its own leap second handling */
 			step_systime(-1.0);
Reproduce the bug
=================

[/etc/ntp.conf]
server 192.168.1.1 minpoll 4 maxpoll 4
restrict 127.0.0.1
driftfile /var/lib/ntp/ntp.drift
logconfig +clockall +peerall +sysall +syncall

[/etc/default/ntp]
NTPD_OPTS='-g -x'
(kernel discipline = disabled, step threshold = 600s)

[gettimeofday]
08:59:59.030832
08:59:59.131288
08:59:59.231760
08:59:59.332231
08:59:59.432694
08:59:59.533090
08:59:59.633326
08:59:59.733779
08:59:59.834248
08:59:59.934619
09:00:00.036123 ***
09:00:00.136485 ***
09:00:00.236819 ***
09:00:00.337119 ***
08:59:59.437500 *** <= leap inserted (BUG)
08:59:59.537772 ***
08:59:59.638119 ***
08:59:59.738468 ***
08:59:59.838833 ***
08:59:59.939141 ***
09:00:00.039497
09:00:00.139845
09:00:00.240152
09:00:00.340494
09:00:00.440839
09:00:00.541123
09:00:00.641402
09:00:00.741751
09:00:00.842152
09:00:00.942501
09:00:01.042849

[/var/log/daemon.log]
Jul  1 08:55:54 localhost ntpd[30655]: 0.0.0.0 c612 02 freq_set ntpd 12.063 PPM
Jul  1 08:55:54 localhost ntpd[30655]: 0.0.0.0 c615 05 clock_sync
Jul  1 08:55:54 localhost ntpd[30655]: 192.168.1.1 9669 89 leap_armed
Jul  1 08:59:59 localhost ntpd[30655]: 0.0.0.0 061b 0b leap_event
TEST1. Ignore a leap (Confirm that the bug is fixed)
====================================================

[/etc/ntp.conf]
server 192.168.1.1 minpoll 4 maxpoll 4
restrict 127.0.0.1
driftfile /var/lib/ntp/ntp.drift
logconfig +clockall +peerall +sysall +syncall

[/etc/default/ntp]
NTPD_OPTS='-g -x'
(kernel discipline = disabled, step threshold = 600s)

[gettimeofday]
08:59:59.013771
08:59:59.114121
08:59:59.214465
08:59:59.314810
08:59:59.415155
08:59:59.515503
08:59:59.615855
08:59:59.716190
08:59:59.816540
08:59:59.916888
09:00:00.017192
09:00:00.117511
09:00:00.217841
09:00:00.318188
09:00:00.418638
09:00:00.519001
09:00:00.619352
09:00:00.719697
09:00:00.820080
09:00:00.920395
09:00:01.020694

[/var/log/daemon.log]
Jul  1 08:55:53 localhost ntpd[2387]: 0.0.0.0 c612 02 freq_set ntpd -3.683 PPM
Jul  1 08:55:53 localhost ntpd[2387]: 0.0.0.0 c615 05 clock_sync
Jul  1 08:55:53 localhost ntpd[2387]: 192.168.1.1 9669 89 leap_armed
Jul  1 09:00:00 localhost ntpd[2387]: Ignoring leap second
Jul  1 09:00:00 localhost ntpd[2387]: 0.0.0.0 061b 0b leap_event


TEST2. Insert a leap
====================

[/etc/ntp.conf]
server 192.168.1.1 minpoll 4 maxpoll 4
restrict 127.0.0.1
driftfile /var/lib/ntp/ntp.drift
logconfig +clockall +peerall +sysall +syncall
disable kernel
tinker step 0.9
(kernel discipline = disabled, step threshold = 0.9s)

[/etc/default/ntp]
NTPD_OPTS='-g'

[gettimeofday]
08:59:59.003013
08:59:59.103466
08:59:59.203933
08:59:59.304400
08:59:59.404866
08:59:59.505334
08:59:59.605797
08:59:59.706261
08:59:59.806726
08:59:59.907194
09:00:00.007487 ***
09:00:00.107911 ***
09:00:00.208268 ***
09:00:00.308534 ***
09:00:00.408868 ***
09:00:00.509218 ***
09:00:00.609559 ***
09:00:00.709903 ***
08:59:59.810241 *** <= leap inserted
08:59:59.910588 ***
09:00:00.010933
09:00:00.111186
09:00:00.211534
09:00:00.311896
09:00:00.412240
09:00:00.512593
09:00:00.612989
09:00:00.713483
09:00:00.813951
09:00:00.914418
09:00:01.014886

[/var/log/daemon.log]
Jul  1 08:55:53 localhost ntpd[6643]: 0.0.0.0 c612 02 freq_set ntpd -3.662 PPM
Jul  1 08:55:53 localhost ntpd[6643]: 0.0.0.0 c615 05 clock_sync
Jul  1 08:55:53 localhost ntpd[6643]: 192.168.1.1 9669 89 leap_armed
Jul  1 08:59:59 localhost ntpd[6643]: Inserting positive leap second
Jul  1 08:59:59 localhost ntpd[6643]: 0.0.0.0 061b 0b leap_event
Reproduce the bug
=================

[/etc/ntp.conf]
server 192.168.1.1 minpoll 4 maxpoll 4
restrict 127.0.0.1
driftfile /var/lib/ntp/ntp.drift
logconfig +clockall +peerall +sysall +syncall

[/etc/default/ntp]
NTPD_OPTS='-g -x'
(kernel discipline = disabled, step threshold = 600s)

[gettimeofday]
08:59:59.044291
08:59:59.144460
08:59:59.244626
08:59:59.344791
08:59:59.444967
08:59:59.545140
08:59:59.645310
08:59:59.745479
08:59:59.845633
08:59:59.945795
09:00:00.045952 ***
09:00:00.146127 ***
09:00:00.246289 ***
09:00:00.346465 ***
09:00:00.446624 ***
08:59:59.546788 *** <= leap inserted (BUG)
08:59:59.646945 ***
08:59:59.747088 ***
08:59:59.847230 ***
08:59:59.947390 ***
09:00:00.047549
09:00:00.147706
09:00:00.247864
09:00:00.348014
09:00:00.448161
09:00:00.548308
09:00:00.648476
09:00:00.748644
09:00:00.848791
09:00:00.948926
09:00:01.049089

[/var/log/daemon.log]
Jul  1 08:55:52 paleale ntpd[2362]: 0.0.0.0 c612 02 freq_set ntpd 508.464 PPM
Jul  1 08:55:52 paleale ntpd[2362]: 0.0.0.0 c615 05 clock_sync
Jul  1 08:55:52 paleale ntpd[2362]: 192.168.1.1 9669 89 leap_armed
Jul  1 08:59:59 paleale ntpd[2362]: 0.0.0.0 061b 0b leap_event
TEST1. Ignore a leap (Confirm that the bug is fixed)
====================================================

[/etc/ntp.conf]
server 192.168.1.1 minpoll 4 maxpoll 4
restrict 127.0.0.1
driftfile /var/lib/ntp/ntp.drift
logconfig +clockall +peerall +sysall +syncall

[/etc/default/ntp]
NTPD_OPTS='-g -x'
(kernel discipline = disabled, step threshold = 600s)

[gettimeofday]
08:59:59.040070
08:59:59.140230
08:59:59.240403
08:59:59.340564
08:59:59.440728
08:59:59.540902
08:59:59.641046
08:59:59.741216
08:59:59.841391
08:59:59.941570
09:00:00.041742
09:00:00.141898
09:00:00.242051
09:00:00.342216
09:00:00.442379
09:00:00.542548
09:00:00.642720
09:00:00.742888
09:00:00.843043
09:00:00.943195
09:00:01.043361

[/var/log/daemon.log]
Jul  1 08:55:52 paleale ntpd[24879]: 0.0.0.0 c612 02 freq_set ntpd 508.416 PPM
Jul  1 08:55:52 paleale ntpd[24879]: 0.0.0.0 c615 05 clock_sync
Jul  1 08:55:52 paleale ntpd[24879]: 192.168.1.1 9669 89 leap_armed
Jul  1 08:57:44 paleale ntpd[24879]: 192.168.1.1 967d 8d popcorn 0.007995 s
Jul  1 09:00:00 paleale ntpd[24879]: Ignoring leap second
Jul  1 09:00:00 paleale ntpd[24879]: 0.0.0.0 061b 0b leap_event


TEST2. Insert a leap
====================

[/etc/ntp.conf]
server 192.168.1.1 minpoll 4 maxpoll 4
restrict 127.0.0.1
driftfile /var/lib/ntp/ntp.drift
logconfig +clockall +peerall +sysall +syncall
disable kernel
tinker step 0.9
(kernel discipline = disabled, step threshold = 0.9s)

[/etc/default/ntp]
NTPD_OPTS='-g'

[gettimeofday]
08:59:59.088779
08:59:59.188946
08:59:59.289113
08:59:59.389297
08:59:59.489481
08:59:59.589652
08:59:59.689829
08:59:59.789984
08:59:59.890177
08:59:59.990345
09:00:00.090510 ***
09:00:00.190676 ***
09:00:00.290837 ***
09:00:00.391011 ***
09:00:00.491176 ***
09:00:00.591345 ***
09:00:00.691527 ***
08:59:59.791663 *** <= leap inserted
08:59:59.891817 ***
08:59:59.991968 ***
09:00:00.092102
09:00:00.192242
09:00:00.292352
09:00:00.392495
09:00:00.492624
09:00:00.592754
09:00:00.692892
09:00:00.793038
09:00:00.893192
09:00:00.993324
09:00:01.093499

[/var/log/daemon.log]
Jul  1 08:55:52 paleale ntpd[25094]: 0.0.0.0 c612 02 freq_set ntpd 508.390 PPM
Jul  1 08:55:52 paleale ntpd[25094]: 0.0.0.0 c615 05 clock_sync
Jul  1 08:55:52 paleale ntpd[25094]: 192.168.1.1 9669 89 leap_armed
Jul  1 08:59:59 paleale ntpd[25094]: Inserting positive leap second
Jul  1 08:59:59 paleale ntpd[25094]: 0.0.0.0 061b 0b leap_event

Reply via email to