Miroslav Lichvar [Tue, 23 Nov 2021 13:41:08 +0000 (14:41 +0100)]
main: add assertions for timespec signedness
Some of the code (e.g. util and clientlog) may work with negative
values. Require that time_t and the tv_nsec types are signed. This seems
to be the case on all supported systems, but it it is not required by
POSIX.
Miroslav Lichvar [Tue, 23 Nov 2021 12:17:26 +0000 (13:17 +0100)]
util: reset GetRandom functions in helpers after fork
Close /dev/urandom and drop cached getrandom() data after forking helper
processes to avoid them getting the same sequence of random numbers
(e.g. two NTS-KE helpers generating cookies with identical nonces).
arc4random() is assumed to be able to detect forks and reseed
automatically.
This is not strictly necessary with the current code, which does not use
the GetRandom functions before the NTS-KE helper processes are forked,
but that could change in future.
Also, call the reset function before exit to close /dev/urandom in order
to avoid valgrind reporting the file object as "still reachable".
Miroslav Lichvar [Tue, 23 Nov 2021 09:35:22 +0000 (10:35 +0100)]
ntp: fix exp1 EF search in process_response()
Don't ignore the magic field when searching for the exp1 extension
field in a received response. If there were two exp1 fields in the
packet, and only one of them had the expected magic value, it should
pick the right one.
Fixes: 2319f72b29a9 ("ntp: add client support for experimental extension field")
Miroslav Lichvar [Mon, 22 Nov 2021 15:44:24 +0000 (16:44 +0100)]
ntp: make default NTP version with xleave to be always 4
If the xleave option is enabled, ignore the key option and the hash
length. Always use version 4 as the default to get interleaved responses
from new chrony servers.
Miroslav Lichvar [Mon, 22 Nov 2021 14:52:01 +0000 (15:52 +0100)]
ntp: suppress monotonic timestamp if smoothing is enabled
Frequency transfer and time smoothing are conflicting features. Set the
monotonic timestamp in the experimental extension field to zero
(invalid) if time smoothing is activated.
Miroslav Lichvar [Mon, 22 Nov 2021 10:39:29 +0000 (11:39 +0100)]
ntp: add special value to experimental root delay/disp
The maximum value of the new 32-bit fields is slightly less than 16,
which can cause the NTP test #7 to pass for a server which has a zero
root delay but maximum root dispersion.
Interpret the maximum value as the maximum value of the original 32-bit
fields (~65536.0 seconds) for better compatibility with NTPv4.
Miroslav Lichvar [Mon, 15 Nov 2021 09:08:34 +0000 (10:08 +0100)]
ntp: add client support for experimental extension field
Add "extfield F323" option to include the new extension field in
requests. If the server responds with this field, use the root
delay/dispersion and monotonic timestamp. Accumulate changes in the
offset between the monotonic and real-time receive timestamps and use
it for the correction of previous offsets in sourcestats. In the
interleaved mode, cancel out the latest change in the offset in
timestamps of the previous request and response, which were captured
before the change actually happened.
Miroslav Lichvar [Wed, 10 Nov 2021 13:56:31 +0000 (14:56 +0100)]
ntp: add server support for experimental extension field
Maintain a server monotonic timescale needed for the experimental
extension field. It follows the best estimate of frequency without
time corrections. Implement it as an offset relative to the NTP time,
starting at zero, using a slew handler to cancel time corrections of the
NTP clock. The 32-bit epoch ID is set to a random value on start and
every step of the system clock.
Miroslav Lichvar [Wed, 10 Nov 2021 13:52:04 +0000 (14:52 +0100)]
ntp: add pre-NTPv5 experimental extension field
Add an experimental extension field for some features that were proposed
for NTPv5. Higher-resolution root delay and dispersion (using 28-bit
fraction) are added. A monotonic receive timestamp will allow a
frequency transfer between the server and client. The client will be
able to separate the server's time corrections from frequency
corrections by tracking the offset between the real-time and monotonic
receive timestamps.
The field has a type of 0xF323 from the new experimental range proposed
by the NTP working group. Include a magic 32-bit value in the field to
avoid interoperability issues if a different implementation choses the
same type for its own experimental field. The value will be changed on
incompatible changes to avoid issues between two different chrony
versions.
ntp: prepare for non-authentication extension fields
Add a new variable to the packet info structure with flags for extension
fields included in received packets and add a new parameter to
transmit_packet() to add the fields to transmitted packets.
ntp: move initial packet parsing from ntp_auth to ntp_core
Since commit fdfcabd79bd3 ("ntp: drop support for long NTPv4 MACs"), the
parser doesn't need to check validify of MACs in NTPv4 packets to
distinguish them from extension fields. Move the parser to ntp_core to
avoid having a separate iteration looking for non-authentication
extension fields.
Miroslav Lichvar [Tue, 26 Oct 2021 13:40:09 +0000 (15:40 +0200)]
socket: increase message buffer length
Add extra space to the socket message buffer to be able to receive
maximum-length NTP-over-PTP SW/HW-timestamped messages from the Linux
error queue (which are looped back as layer-2 frames).
Miroslav Lichvar [Tue, 26 Oct 2021 12:41:49 +0000 (14:41 +0200)]
ntp: use previous root delay/disp in interleaved mode
When calculating the root delay and dispersion of a sample measured in
the interleaved mode, use the root delay and dispersion values from
the previous response (to which the TX timestamp corresponds). If the TX
timestamp is combined with the RX timestamp of the latest response (e.g.
in the symmetric mode), use the maximum of the previous and latest root
delay/dispersion.
Miroslav Lichvar [Mon, 25 Oct 2021 15:00:28 +0000 (17:00 +0200)]
clientlog: undo clock adjustments in updated TX timestamps
When the server clock was updated between saving of the RX timestamp and
updating the TX timestamp, a client using interleaved mode with the four
timestamps which minimize error in measured delay (e.g. chrony) had the
server clock adjustment included in the measured delay, which could
disrupt the sample filtering and weighting.
Add a handler to track the slew epoch and remember the last offset. Undo
the adjustment in TX timestamps which have their RX timestamp in the
previous epoch to fix the delay observed by the clients.
If an unknown clock step is detected, drop all timestamps.
Miroslav Lichvar [Mon, 25 Oct 2021 08:23:41 +0000 (10:23 +0200)]
ntp: don't save timestamps if transmit_packet() failed
Don't save server RX and TX timestamp to clientlog if the transmission
or authentication failed (e.g. packet is handled in ntp_signd). They
will not be needed.
Miroslav Lichvar [Mon, 25 Oct 2021 08:18:27 +0000 (10:18 +0200)]
ntp: initialize saved TX timestamp
Zero the initial TX timestamp which is saved for the interleaved
mode in case there is no previous timestamp saved in clientlog and
transmit_packet() does not generate a new one (e.g. due to failure in
authentication).
Fixes: 5f4cbaab7e0e ("ntp: optimize detection of clients using interleaved mode")
Miroslav Lichvar [Thu, 14 Oct 2021 10:03:49 +0000 (12:03 +0200)]
ntp: optimize detection of clients using interleaved mode
Use the lowest bit of the server RX and TX timestamp as a flag
indicating RX timestamp. This allows the server to detect potential
interleaved requests without having to save all its RX timestamps. It
significantly reduces the amount of memory needed to support clients
using the interleaved mode if most of the server's clients are using the
basic mode (e.g. a public server).
Capture the TX timestamp on the first response to the request which has
the flag set to not further delay the first interleaved response.
False positives are possible with broken clients which set the origin
timestamp to something else than zero or the server RX or TX timestamp.
This causes an unnecessary RX timestamp to be saved and TX timestamp
captured and saved.
Miroslav Lichvar [Thu, 14 Oct 2021 09:52:21 +0000 (11:52 +0200)]
ntp: move authentication calls in transmit_packet()
Move the calls resetting and generating authentication data out of the
loop checking for unique TX timestamp. This allows the timestamps to be
manipulated after the check.
Miroslav Lichvar [Mon, 11 Oct 2021 11:27:35 +0000 (13:27 +0200)]
clientlog: separate NTP timestamps from IP addresses
Instead of keeping one pair of RX and TX timestamp for each address, add
a separate RX->TX map using an ordered circular buffer. Save the RX
timestamps as 64-bit integers and search them with a combined linear
interpolation and binary algorithm.
This enables the server to support multiple interleaved clients sharing
the same IP address (e.g. NAT) and it will allow other improvements to
be implemented later. A drawback is that a single broken client sending
interleaved requests at a high rate (without spoofing the source
address) can now prevent clients on other addresses from getting
interleaved responses.
The total number of saved timestamps does not change. It's still
determined by the clientloglimit directive. A new option may be added
later if needed. The whole buffer is allocated at once, but only on
first use to not waste memory on client-only configurations.
sys_linux: fix seccomp filter for BINDTODEVICE option
The BINDTODEVICE socket option is the first option in the seccomp filter
setting a string instead of int. Remove the length check from the
setsockopt rules to allow a device name longer than 3 characters.
This was reported in Debian bug #995207.
Fixes: b9f5ce83b02e ("sys_linux: allow BINDTODEVICE option in seccomp filter")
Miroslav Lichvar [Wed, 29 Sep 2021 13:25:48 +0000 (15:25 +0200)]
examples: harden systemd services
Add various settings to the example chronyd and chrony-wait services to
decrease the exposure reported by the "systemd-analyze security"
command. The original exposure was high as the analyzer does not check
the actual process (e.g. that it dropped the root privileges or that it
has its own seccomp filter).
Limit read-write access to /run, /var/lib/chrony, and /var/spool.
Access to /run (instead of /run/chrony) is needed for the refclock
socket expected by gpsd.
The mailonchange directive is most likely to break as it executes
/usr/sbin/sendmail, which can do unexpected operations depending on the
implementation. It should work with a setuid/setgid binary, but it is
not expected to write outside of /var/spool and the private /tmp.
Miroslav Lichvar [Thu, 23 Sep 2021 11:00:24 +0000 (13:00 +0200)]
ntp: check software timestamps on Linux
Apparently some routers with hardware NAT acceleration have a bug
causing the kernel timestamps to be corrupted and break NTP. Similarly
to the sanity check applied to hardware timestamps, require the
kernel/driver timestamps to be within one second of the daemon timestamp
to be accepted.
Miroslav Lichvar [Thu, 23 Sep 2021 07:34:47 +0000 (09:34 +0200)]
test: fix incorrect use of RAND_MAX
On some systems (e.g. Solaris/OpenIndiana) rand() and random() have
different ranges. RAND_MAX is the maximum value returned by rand(),
but random() should always have a range of 0 through 2^31-1.
Miroslav Lichvar [Wed, 22 Sep 2021 15:06:38 +0000 (17:06 +0200)]
client: replace allow/deny parser
Use the new cmdparse function for parsing the (cmd)allow/deny commands
and refactor the code a bit to reduce the number of functions needed for
all the (cmd)allow/deny(all) combinations.
Miroslav Lichvar [Wed, 22 Sep 2021 13:54:50 +0000 (15:54 +0200)]
conf: rework allow/deny parser
Refactor the (cmd)allow/deny parser and make it more strict in what
input it accepts. Check the scanned numbers and require whole input to
be processed.
Move the parser to cmdparse to make it available to the client.
gnutls running in the FIPS140-2 mode does not allow MD5 to be
initialized, which breaks chronyd using MD5 to calculate reference ID
of IPv6 addresses. Specify a new hash algorithm for non-security MD5 use
and temporarily switch to the lax mode when initializing the hash
function.
Add support for crypto hash functions in gnutls (internally using
nettle). This can be useful to avoid directly linking with nettle to
avoid ABI breaks.
gnutls_aead_cipher_init() is declared in gnutls/crypto.h. If the
compiler handles implicit declarations as errors, the SIV support was
not detected. Fix the check to use the correct header.
Miroslav Lichvar [Wed, 18 Aug 2021 10:42:07 +0000 (12:42 +0200)]
ntp: add support for NTP over PTP
Allow NTP messages to be exchanged as a payload of PTP messages to
enable full hardware timestamping on NICs that can timestamp PTP packets
only. Implemented is the protocol described in this draft (version 00):
This is an experimental feature. It can be changed or removed in future.
The used PTP domain is 123 and the NTP TLV type is 0x2023 from the "do
not propagate" experimental range.
The ptpport directive enables NTP-over-PTP as a server and as a client
for all sources that have the port option set to the PTP port. The port
should be the PTP event port (319) to trigger timestamping in the
hardware.
The implementation is contained to ntp_io. It is transparent to
ntp_core.
A while back, support for memory locking and real-time scheduling was
added to more platforms. The chronyd documentation wasn't updated at
that time (chronyd.conf was). This patch fixes that.
With the latest glibc it's now possible to define _TIME_BITS=64 to get
64-bit time_t on 32-bit Linux systems. This breaks the %ld printf/scanf
modifier used with the RTC drift timestamp. Process it as a double.
The files are read after dropping root privileges. They need to be
readable by the chrony user. The error message "Could not set
credentials : Error while reading file." does not make this requirement
very obvious.
Miroslav Lichvar [Mon, 10 May 2021 16:08:33 +0000 (18:08 +0200)]
test: allow inaccurate math in util unit test
Don't require timespec/timeval-double conversion tests to produce
correctly rounded results to handle x86 and other archs with wider
intermediate results.
Add level "2" to enable a filter which blocks only specific system calls
like fork and exec* instead of blocking everything unknown. It should
be reliable with respect to changes in libraries, but it provides only a
very limited protection.
When loading a dump file with the -r option, check also sanity of the
sample time, offset, peer/root delay/dispersion, and the sample order to
better handle corrupted files.
source: don't print duplicated address in selection message
Don't print the original IP address in parentheses in the "Selected
source ..." message if it is identical to the current address. That is
expected to be the usual case for sources specified by IP address.
Log an error message when adding of a source fails, e.g. due to the new
limit on number of sources, or when the same address is specified
multiple times.
In the NTS-KE client don't reject the response if it has non-critical
records that are too long for the processing buffer. This is not
expected to happen with the current specification, but it might be
needed with future extensions.
Fixes: 7925ed39b81f ("nts: fix handling of long server negotiation record")
Miroslav Lichvar [Tue, 27 Apr 2021 13:39:59 +0000 (15:39 +0200)]
nts: avoid assumption about cookie record
The cookie record is currently assumed to be the longest record that
needs to be accepted by the client, but that does not have to be always
the case. Define the processing buffer using the maximum body record
constant instead and add an assertion to make sure it's not smaller than
the maximum accepted cookie length.
Miroslav Lichvar [Tue, 27 Apr 2021 09:18:04 +0000 (11:18 +0200)]
nts: fix handling of long server negotiation record
Recent change in handling of the NTPv4 server negotiation record (commit 754097944be2) increased the length of the instance name buffer to make
room for the trailing dot. This allowed a record with body truncated in
the processing buffer to be accepted and caused an over-read of 1 byte
in the memcpy() call saving the name to the instance buffer.
Modify the client to accept only records that fit in the processing
buffer.
Fixes: 754097944be2 ("nts: handle negotiated server as FQDN")
Miroslav Lichvar [Wed, 21 Apr 2021 07:37:40 +0000 (09:37 +0200)]
nts: handle negotiated server as FQDN
The NTS RFC requires the recipient of the Server Negotiation NTS-KE
record to handle the name as a fully qualified domain name. Add a
trailing dot if not present to force the name to be resolved as one.
sys_timex: remove workaround for broken ntp_adjtime on macOS
Early beta releases of macOS Big Sur had a signed/unsigned error in
Apple's implementation of ntp_adjtime. Apple have since fixed this error
and the workaround is no longer required.
Miroslav Lichvar [Thu, 15 Apr 2021 07:43:01 +0000 (09:43 +0200)]
conf: require sourcedir files to be terminated by newline
When reading a *.sources file require that each line is termined by the
newline character to avoid processing an unfinished line, e.g. due to an
unexpected call of the reload command when the file is being written in
place.