diff --git a/SOURCES/chrony-smoothleap.patch b/SOURCES/chrony-smoothleap.patch new file mode 100644 index 0000000..34af532 --- /dev/null +++ b/SOURCES/chrony-smoothleap.patch @@ -0,0 +1,78 @@ +commit c0a8afdb68694a31045111c6d7481c2cced34a34 +Author: Miroslav Lichvar +Date: Mon Sep 12 12:23:09 2016 +0200 + + smooth: fix selection of 1st stage direction + + When the smoothing process is updated with extremely small (e.g. + sub-nanosecond) values, both directions may give a negative length of + the 1st or 3rd stage due to numerical errors and the selection will fail + an in assertion. Rework the code to select the direction which gives a + smaller error. + +diff --git a/smooth.c b/smooth.c +index 4fa037b..08b80ba 100644 +--- a/smooth.c ++++ b/smooth.c +@@ -137,7 +137,7 @@ get_smoothing(struct timespec *now, double *poffset, double *pfreq, + static void + update_stages(void) + { +- double s1, s2, s, l1, l2, l3, lc, f, f2; ++ double s1, s2, s, l1, l2, l3, lc, f, f2, l1t[2], l3t[2], err[2]; + int i, dir; + + /* Prepare the three stages so that the integral of the frequency offset +@@ -146,22 +146,41 @@ update_stages(void) + s1 = smooth_offset / max_wander; + s2 = smooth_freq * smooth_freq / (2.0 * max_wander * max_wander); + +- l1 = l2 = l3 = 0.0; +- + /* Calculate the lengths of the 1st and 3rd stage assuming there is no +- frequency limit. If length of the 1st stage comes out negative, switch +- its direction. */ +- for (dir = -1; dir <= 1; dir += 2) { ++ frequency limit. The direction of the 1st stage is selected so that ++ the lengths will not be negative. With extremely small offsets both ++ directions may give a negative length due to numerical errors, so select ++ the one which gives a smaller error. */ ++ ++ for (i = 0, dir = -1; i <= 1; i++, dir += 2) { ++ err[i] = 0.0; + s = dir * s1 + s2; +- if (s >= 0.0) { +- l3 = sqrt(s); +- l1 = l3 - dir * smooth_freq / max_wander; +- if (l1 >= 0.0) +- break; ++ ++ if (s < 0.0) { ++ err[i] += -s; ++ s = 0.0; + } ++ ++ l3t[i] = sqrt(s); ++ l1t[i] = l3t[i] - dir * smooth_freq / max_wander; ++ ++ if (l1t[i] < 0.0) { ++ err[i] += l1t[i] * l1t[i]; ++ l1t[i] = 0.0; ++ } ++ } ++ ++ if (err[0] < err[1]) { ++ l1 = l1t[0]; ++ l3 = l3t[0]; ++ dir = -1; ++ } else { ++ l1 = l1t[1]; ++ l3 = l3t[1]; ++ dir = 1; + } + +- assert(dir <= 1 && l1 >= 0.0 && l3 >= 0.0); ++ l2 = 0.0; + + /* If the limit was reached, shorten 1st+3rd stages and set a 2nd stage */ + f = dir * smooth_freq + l1 * max_wander - max_freq; diff --git a/SPECS/chrony.spec b/SPECS/chrony.spec index 7a1b6ce..b0eb628 100644 --- a/SPECS/chrony.spec +++ b/SPECS/chrony.spec @@ -4,7 +4,7 @@ Name: chrony Version: 2.1.1 -Release: 3%{?dist} +Release: 4%{?dist} Summary: An NTP client/server Group: System Environment/Daemons @@ -24,6 +24,8 @@ Source11: chrony-dnssrv@.service Source12: chrony-dnssrv@.timer %{?gitpatch:Patch0: chrony-%{version}%{?prerelease}-%{gitpatch}.patch.gz} +Patch1: chrony-smoothleap.patch + BuildRequires: libcap-devel libedit-devel nss-devel pps-tools-devel BuildRequires: bison texinfo systemd-units @@ -41,12 +43,13 @@ clocks, system real-time clock or manual input as time references. %if 0%{!?vendorzone:1} %{?fedora: %global vendorzone fedora.} -%{?rhel: %global vendorzone centos.} +%{?rhel: %global vendorzone rhel.} %endif %prep %setup -q -n %{name}-%{version}%{?prerelease} -a 10 %{?gitpatch:%patch0 -p1} +%patch1 -p1 -b .smoothleap %{?gitpatch: echo %{version}-%{gitpatch} > version.txt} @@ -147,8 +150,8 @@ fi %dir %attr(-,chrony,chrony) %{_localstatedir}/log/chrony %changelog -* Thu Nov 03 2016 CentOS Sources - 2.1.1-3.el7.centos -- rebrand vendorzone +* Fri Nov 18 2016 Miroslav Lichvar 2.1.1-4 +- fix crash with smoothtime leaponly directive (#1392793) * Tue Jun 28 2016 Miroslav Lichvar 2.1.1-3 - fix chrony-helper to exit with correct status (#1350531)