mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-04 16:05:07 -05:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
885e7774fd | ||
|
|
883b7eed8a | ||
|
|
4049ed8766 | ||
|
|
f9f6803b8a | ||
|
|
385f7ebfd9 | ||
|
|
f9cbc4803d | ||
|
|
97973b1833 | ||
|
|
9cdfc15e31 | ||
|
|
fc99317291 | ||
|
|
bb9ba3e4bd | ||
|
|
649f54a1e6 | ||
|
|
4070d7ffa6 | ||
|
|
0493abb68a | ||
|
|
8c1e16711d | ||
|
|
1d03908646 | ||
|
|
49d718c025 | ||
|
|
c536b2561b | ||
|
|
b9f5ce83b0 | ||
|
|
8baab00ae0 | ||
|
|
d01cb5af46 | ||
|
|
7925ed39b8 |
2
NEWS
2
NEWS
@@ -12,7 +12,7 @@ Enhancements
|
|||||||
* Increase PPS lock limit to 40% of pulse interval
|
* Increase PPS lock limit to 40% of pulse interval
|
||||||
* Perform source selection immediately after loading dump files
|
* Perform source selection immediately after loading dump files
|
||||||
* Reload dump files for addresses negotiated by NTS-KE server
|
* Reload dump files for addresses negotiated by NTS-KE server
|
||||||
* Update seccomp filter
|
* Update seccomp filter and add less restrictive level
|
||||||
* Restart ongoing name resolution on online command
|
* Restart ongoing name resolution on online command
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
|
|||||||
4
client.c
4
client.c
@@ -4,7 +4,7 @@
|
|||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
* Copyright (C) Lonnie Abelbeck 2016, 2018
|
* Copyright (C) Lonnie Abelbeck 2016, 2018
|
||||||
* Copyright (C) Miroslav Lichvar 2009-2020
|
* Copyright (C) Miroslav Lichvar 2009-2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -3458,7 +3458,7 @@ static void
|
|||||||
display_gpl(void)
|
display_gpl(void)
|
||||||
{
|
{
|
||||||
printf("chrony version %s\n"
|
printf("chrony version %s\n"
|
||||||
"Copyright (C) 1997-2003, 2007, 2009-2020 Richard P. Curnow and others\n"
|
"Copyright (C) 1997-2003, 2007, 2009-2021 Richard P. Curnow and others\n"
|
||||||
"chrony comes with ABSOLUTELY NO WARRANTY. This is free software, and\n"
|
"chrony comes with ABSOLUTELY NO WARRANTY. This is free software, and\n"
|
||||||
"you are welcome to redistribute it under certain conditions. See the\n"
|
"you are welcome to redistribute it under certain conditions. See the\n"
|
||||||
"GNU General Public License version 2 for details.\n\n",
|
"GNU General Public License version 2 for details.\n\n",
|
||||||
|
|||||||
2
cmdmon.c
2
cmdmon.c
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
* Copyright (C) Miroslav Lichvar 2009-2016, 2018-2020
|
* Copyright (C) Miroslav Lichvar 2009-2016, 2018-2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
|||||||
14
conf.c
14
conf.c
@@ -1793,6 +1793,8 @@ reload_source_dirs(void)
|
|||||||
if (s == NSR_UnresolvedName) {
|
if (s == NSR_UnresolvedName) {
|
||||||
unresolved++;
|
unresolved++;
|
||||||
} else if (s != NSR_Success) {
|
} else if (s != NSR_Success) {
|
||||||
|
LOG(LOGS_ERR, "Could not add source %s", source->params.name);
|
||||||
|
|
||||||
/* Mark the source as not present */
|
/* Mark the source as not present */
|
||||||
source->params.name[0] = '\0';
|
source->params.name[0] = '\0';
|
||||||
}
|
}
|
||||||
@@ -1864,7 +1866,8 @@ CNF_AddInitSources(void)
|
|||||||
ntp_addr.port = cps_source.port;
|
ntp_addr.port = cps_source.port;
|
||||||
cps_source.params.iburst = 1;
|
cps_source.params.iburst = 1;
|
||||||
|
|
||||||
NSR_AddSource(&ntp_addr, NTP_SERVER, &cps_source.params, NULL);
|
if (NSR_AddSource(&ntp_addr, NTP_SERVER, &cps_source.params, NULL) != NSR_Success)
|
||||||
|
LOG(LOGS_ERR, "Could not add source %s", UTI_IPToString(&ntp_addr.ip_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
ARR_SetSize(init_sources, 0);
|
ARR_SetSize(init_sources, 0);
|
||||||
@@ -1877,11 +1880,16 @@ CNF_AddSources(void)
|
|||||||
{
|
{
|
||||||
NTP_Source *source;
|
NTP_Source *source;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
NSR_Status s;
|
||||||
|
|
||||||
for (i = 0; i < ARR_GetSize(ntp_sources); i++) {
|
for (i = 0; i < ARR_GetSize(ntp_sources); i++) {
|
||||||
source = (NTP_Source *)ARR_GetElement(ntp_sources, i);
|
source = (NTP_Source *)ARR_GetElement(ntp_sources, i);
|
||||||
NSR_AddSourceByName(source->params.name, source->params.port,
|
|
||||||
source->pool, source->type, &source->params.params, NULL);
|
s = NSR_AddSourceByName(source->params.name, source->params.port, source->pool,
|
||||||
|
source->type, &source->params.params, NULL);
|
||||||
|
if (s != NSR_Success && s != NSR_UnresolvedName)
|
||||||
|
LOG(LOGS_ERR, "Could not add source %s", source->params.name);
|
||||||
|
|
||||||
Free(source->params.name);
|
Free(source->params.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
configure
vendored
2
configure
vendored
@@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright (C) Richard P. Curnow 1997-2003
|
# Copyright (C) Richard P. Curnow 1997-2003
|
||||||
# Copyright (C) Bryan Christianson 2016
|
# Copyright (C) Bryan Christianson 2016
|
||||||
# Copyright (C) Miroslav Lichvar 2009, 2012-2020
|
# Copyright (C) Miroslav Lichvar 2009, 2012-2021
|
||||||
# Copyright (C) Stefan R. Filipek 2019
|
# Copyright (C) Stefan R. Filipek 2019
|
||||||
#
|
#
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// Copyright (C) Richard P. Curnow 1997-2003
|
// Copyright (C) Richard P. Curnow 1997-2003
|
||||||
// Copyright (C) Stephen Wadeley 2016
|
// Copyright (C) Stephen Wadeley 2016
|
||||||
// Copyright (C) Bryan Christianson 2017
|
// Copyright (C) Bryan Christianson 2017
|
||||||
// Copyright (C) Miroslav Lichvar 2009-2020
|
// Copyright (C) Miroslav Lichvar 2009-2021
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of version 2 of the GNU General Public License as
|
// it under the terms of version 2 of the GNU General Public License as
|
||||||
|
|||||||
@@ -156,18 +156,29 @@ not recommended when the configuration is not known, or at least limited to
|
|||||||
specific directives.
|
specific directives.
|
||||||
|
|
||||||
*-F* _level_::
|
*-F* _level_::
|
||||||
This option configures a system call filter when *chronyd* is compiled with
|
This option configures system call filters loaded by *chronyd* processes if it
|
||||||
support for the Linux secure computing (seccomp) facility. In level 1 the
|
was compiled with support for the Linux secure computing (seccomp) facility.
|
||||||
process is killed when a forbidden system call is made, in level -1 the SIGSYS
|
Three levels are defined: 0, 1, 2. The filters are disabled at level 0. At
|
||||||
signal is thrown instead and in level 0 the filter is disabled. The default
|
levels 1 and 2, *chronyd* will be killed if it makes a system call which is
|
||||||
value is 0.
|
blocked by the filters. The level can be specified as a negative number to
|
||||||
|
trigger the SIGSYS signal instead of SIGKILL, which can be useful for
|
||||||
|
debugging. The default value is 0.
|
||||||
+
|
+
|
||||||
It is recommended to enable the filter only when it is known to work on the
|
At level 1, the filters allow only selected system calls that are normally
|
||||||
version of the system where *chrony* is installed as the filter needs to allow
|
expected to be made by *chronyd*. Other system calls are blocked. This level is
|
||||||
also system calls made from libraries that *chronyd* is using (e.g. libc) and
|
recommended only if it is known to work on the version of the system where
|
||||||
different versions or implementations of the libraries might make different
|
*chrony* is installed. The filters need to allow also system calls made by
|
||||||
system calls. If the filter is missing some system call, *chronyd* could be
|
libraries that *chronyd* is using (e.g. libc), but different versions or
|
||||||
killed even in normal operation.
|
implementations of the libraries might make different system calls. If the
|
||||||
|
filters are missing a system call, *chronyd* could be killed even in normal
|
||||||
|
operation.
|
||||||
|
+
|
||||||
|
At level 2, the filters block only a small number of specific system calls
|
||||||
|
(e.g. fork and exec). This approach should avoid false positives, but the
|
||||||
|
protection of the system against a compromised *chronyd* process is much more
|
||||||
|
limited.
|
||||||
|
+
|
||||||
|
The filters cannot be enabled with the *mailonchange* directive.
|
||||||
|
|
||||||
*-P* _priority_::
|
*-P* _priority_::
|
||||||
On Linux, this option will select the SCHED_FIFO real-time scheduler at the
|
On Linux, this option will select the SCHED_FIFO real-time scheduler at the
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// This file is part of chrony
|
// This file is part of chrony
|
||||||
//
|
//
|
||||||
// Copyright (C) Richard P. Curnow 1997-2003
|
// Copyright (C) Richard P. Curnow 1997-2003
|
||||||
// Copyright (C) Miroslav Lichvar 2014-2016, 2020
|
// Copyright (C) Miroslav Lichvar 2014-2016, 2020-2021
|
||||||
//
|
//
|
||||||
// This program is free software; you can redistribute it and/or modify
|
// This program is free software; you can redistribute it and/or modify
|
||||||
// it under the terms of version 2 of the GNU General Public License as
|
// it under the terms of version 2 of the GNU General Public License as
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
* Copyright (C) Miroslav Lichvar 2011-2012, 2014, 2016, 2020
|
* Copyright (C) Miroslav Lichvar 2011-2012, 2014, 2016, 2020-2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Miroslav Lichvar 2020
|
* Copyright (C) Miroslav Lichvar 2020-2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -127,9 +127,10 @@ process_response(NKC_Instance inst)
|
|||||||
{
|
{
|
||||||
int next_protocol = -1, aead_algorithm = -1, error = 0;
|
int next_protocol = -1, aead_algorithm = -1, error = 0;
|
||||||
int i, critical, type, length;
|
int i, critical, type, length;
|
||||||
uint16_t data[NKE_MAX_COOKIE_LENGTH / sizeof (uint16_t)];
|
uint16_t data[NKE_MAX_RECORD_BODY_LENGTH / sizeof (uint16_t)];
|
||||||
|
|
||||||
assert(NKE_MAX_COOKIE_LENGTH % sizeof (uint16_t) == 0);
|
assert(NKE_MAX_COOKIE_LENGTH <= NKE_MAX_RECORD_BODY_LENGTH);
|
||||||
|
assert(sizeof (data) % sizeof (uint16_t) == 0);
|
||||||
assert(sizeof (uint16_t) == 2);
|
assert(sizeof (uint16_t) == 2);
|
||||||
|
|
||||||
inst->num_cookies = 0;
|
inst->num_cookies = 0;
|
||||||
@@ -141,6 +142,13 @@ process_response(NKC_Instance inst)
|
|||||||
if (!NKSN_GetRecord(inst->session, &critical, &type, &length, &data, sizeof (data)))
|
if (!NKSN_GetRecord(inst->session, &critical, &type, &length, &data, sizeof (data)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (length > sizeof (data)) {
|
||||||
|
DEBUG_LOG("Record too long type=%d length=%d critical=%d", type, length, critical);
|
||||||
|
if (critical)
|
||||||
|
error = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NKE_RECORD_NEXT_PROTOCOL:
|
case NKE_RECORD_NEXT_PROTOCOL:
|
||||||
if (!critical || length != 2 || ntohs(data[0]) != NKE_NEXT_PROTOCOL_NTPV4) {
|
if (!critical || length != 2 || ntohs(data[0]) != NKE_NEXT_PROTOCOL_NTPV4) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Miroslav Lichvar 2020
|
* Copyright (C) Miroslav Lichvar 2020-2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
|||||||
@@ -669,6 +669,8 @@ load_cookies(NNC_Instance inst)
|
|||||||
inst->last_nke_success = context_time + SCH_GetLastEventMonoTime();
|
inst->last_nke_success = context_time + SCH_GetLastEventMonoTime();
|
||||||
inst->context_id = context_id;
|
inst->context_id = context_id;
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
DEBUG_LOG("Loaded %d cookies for %s", i, filename);
|
DEBUG_LOG("Loaded %d cookies for %s", i, filename);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -589,7 +589,7 @@ log_selection_source(const char *format, SRC_Instance inst)
|
|||||||
name = source_to_string(inst);
|
name = source_to_string(inst);
|
||||||
ntp_name = inst->type == SRC_NTP ? NSR_GetName(inst->ip_addr) : NULL;
|
ntp_name = inst->type == SRC_NTP ? NSR_GetName(inst->ip_addr) : NULL;
|
||||||
|
|
||||||
if (ntp_name)
|
if (ntp_name && strcmp(name, ntp_name) != 0)
|
||||||
snprintf(buf, sizeof (buf), "%s (%s)", name, ntp_name);
|
snprintf(buf, sizeof (buf), "%s (%s)", name, ntp_name);
|
||||||
else
|
else
|
||||||
snprintf(buf, sizeof (buf), "%s", name);
|
snprintf(buf, sizeof (buf), "%s", name);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Richard P. Curnow 1997-2003
|
* Copyright (C) Richard P. Curnow 1997-2003
|
||||||
* Copyright (C) Miroslav Lichvar 2011-2014, 2016-2018
|
* Copyright (C) Miroslav Lichvar 2011-2014, 2016-2018, 2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -885,6 +885,7 @@ int
|
|||||||
SST_LoadFromFile(SST_Stats inst, FILE *in)
|
SST_LoadFromFile(SST_Stats inst, FILE *in)
|
||||||
{
|
{
|
||||||
int i, n_samples, arun;
|
int i, n_samples, arun;
|
||||||
|
struct timespec now;
|
||||||
double sample_time;
|
double sample_time;
|
||||||
char line[256];
|
char line[256];
|
||||||
|
|
||||||
@@ -895,6 +896,8 @@ SST_LoadFromFile(SST_Stats inst, FILE *in)
|
|||||||
|
|
||||||
SST_ResetInstance(inst);
|
SST_ResetInstance(inst);
|
||||||
|
|
||||||
|
LCL_ReadCookedTime(&now, NULL);
|
||||||
|
|
||||||
for (i = 0; i < n_samples; i++) {
|
for (i = 0; i < n_samples; i++) {
|
||||||
if (!fgets(line, sizeof (line), in) ||
|
if (!fgets(line, sizeof (line), in) ||
|
||||||
sscanf(line, "%lf %lf %lf %lf %lf %lf %lf",
|
sscanf(line, "%lf %lf %lf %lf %lf %lf %lf",
|
||||||
@@ -903,8 +906,19 @@ SST_LoadFromFile(SST_Stats inst, FILE *in)
|
|||||||
&inst->root_delays[i], &inst->root_dispersions[i]) != 7)
|
&inst->root_delays[i], &inst->root_dispersions[i]) != 7)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!UTI_IsTimeOffsetSane(&now, sample_time - UTI_TimespecToDouble(&now)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Some resolution is lost in the double format, but that's ok */
|
/* Some resolution is lost in the double format, but that's ok */
|
||||||
UTI_DoubleToTimespec(sample_time, &inst->sample_times[i]);
|
UTI_DoubleToTimespec(sample_time, &inst->sample_times[i]);
|
||||||
|
|
||||||
|
/* Make sure the samples are sane and they are in order */
|
||||||
|
if (!UTI_IsTimeOffsetSane(&inst->sample_times[i], -inst->offsets[i]) ||
|
||||||
|
!(fabs(inst->peer_delays[i]) < 1.0e6 && fabs(inst->peer_dispersions[i]) < 1.0e6 &&
|
||||||
|
fabs(inst->root_delays[i]) < 1.0e6 && fabs(inst->root_dispersions[i]) < 1.0e6) ||
|
||||||
|
(i > 0 && UTI_CompareTimespecs(&inst->sample_times[i],
|
||||||
|
&inst->sample_times[i - 1]) <= 0))
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inst->n_samples = n_samples;
|
inst->n_samples = n_samples;
|
||||||
|
|||||||
77
sys_linux.c
77
sys_linux.c
@@ -486,7 +486,7 @@ void check_seccomp_applicability(void)
|
|||||||
void
|
void
|
||||||
SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
||||||
{
|
{
|
||||||
const int syscalls[] = {
|
const int allowed[] = {
|
||||||
/* Clock */
|
/* Clock */
|
||||||
SCMP_SYS(adjtimex),
|
SCMP_SYS(adjtimex),
|
||||||
SCMP_SYS(clock_adjtime),
|
SCMP_SYS(clock_adjtime),
|
||||||
@@ -508,6 +508,7 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
|||||||
SCMP_SYS(getpid),
|
SCMP_SYS(getpid),
|
||||||
SCMP_SYS(getrlimit),
|
SCMP_SYS(getrlimit),
|
||||||
SCMP_SYS(getuid),
|
SCMP_SYS(getuid),
|
||||||
|
SCMP_SYS(getuid32),
|
||||||
SCMP_SYS(rt_sigaction),
|
SCMP_SYS(rt_sigaction),
|
||||||
SCMP_SYS(rt_sigreturn),
|
SCMP_SYS(rt_sigreturn),
|
||||||
SCMP_SYS(rt_sigprocmask),
|
SCMP_SYS(rt_sigprocmask),
|
||||||
@@ -613,6 +614,22 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
|||||||
SCMP_SYS(uname),
|
SCMP_SYS(uname),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int denied_any[] = {
|
||||||
|
SCMP_SYS(execve),
|
||||||
|
#ifdef __NR_execveat
|
||||||
|
SCMP_SYS(execveat),
|
||||||
|
#endif
|
||||||
|
SCMP_SYS(fork),
|
||||||
|
SCMP_SYS(ptrace),
|
||||||
|
SCMP_SYS(vfork),
|
||||||
|
};
|
||||||
|
|
||||||
|
const int denied_ntske[] = {
|
||||||
|
SCMP_SYS(ioctl),
|
||||||
|
SCMP_SYS(setsockopt),
|
||||||
|
SCMP_SYS(socket),
|
||||||
|
};
|
||||||
|
|
||||||
const int socket_domains[] = {
|
const int socket_domains[] = {
|
||||||
AF_NETLINK, AF_UNIX, AF_INET,
|
AF_NETLINK, AF_UNIX, AF_INET,
|
||||||
#ifdef FEAT_IPV6
|
#ifdef FEAT_IPV6
|
||||||
@@ -624,6 +641,9 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
|||||||
{ SOL_IP, IP_PKTINFO }, { SOL_IP, IP_FREEBIND }, { SOL_IP, IP_TOS },
|
{ SOL_IP, IP_PKTINFO }, { SOL_IP, IP_FREEBIND }, { SOL_IP, IP_TOS },
|
||||||
#ifdef FEAT_IPV6
|
#ifdef FEAT_IPV6
|
||||||
{ SOL_IPV6, IPV6_V6ONLY }, { SOL_IPV6, IPV6_RECVPKTINFO },
|
{ SOL_IPV6, IPV6_V6ONLY }, { SOL_IPV6, IPV6_RECVPKTINFO },
|
||||||
|
#endif
|
||||||
|
#ifdef SO_BINDTODEVICE
|
||||||
|
{ SOL_SOCKET, SO_BINDTODEVICE },
|
||||||
#endif
|
#endif
|
||||||
{ SOL_SOCKET, SO_BROADCAST }, { SOL_SOCKET, SO_REUSEADDR },
|
{ SOL_SOCKET, SO_BROADCAST }, { SOL_SOCKET, SO_REUSEADDR },
|
||||||
#ifdef SO_REUSEPORT
|
#ifdef SO_REUSEPORT
|
||||||
@@ -662,31 +682,65 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned int default_action, deny_action;
|
||||||
scmp_filter_ctx *ctx;
|
scmp_filter_ctx *ctx;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Sign of the level determines the deny action (kill or SIGSYS).
|
||||||
|
At level 1, selected syscalls are allowed, others are denied.
|
||||||
|
At level 2, selected syscalls are denied, others are allowed. */
|
||||||
|
|
||||||
|
deny_action = level > 0 ? SCMP_ACT_KILL : SCMP_ACT_TRAP;
|
||||||
|
if (level < 0)
|
||||||
|
level = -level;
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case 1:
|
||||||
|
default_action = deny_action;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
default_action = SCMP_ACT_ALLOW;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_FATAL("Unsupported filter level");
|
||||||
|
}
|
||||||
|
|
||||||
if (context == SYS_MAIN_PROCESS) {
|
if (context == SYS_MAIN_PROCESS) {
|
||||||
/* Check if the chronyd configuration is supported */
|
/* Check if the chronyd configuration is supported */
|
||||||
check_seccomp_applicability();
|
check_seccomp_applicability();
|
||||||
|
|
||||||
/* Start the helper process, which will run without any seccomp filter. It
|
/* At level 1, start a helper process which will not have a seccomp filter.
|
||||||
will be used for getaddrinfo(), for which it's difficult to maintain a
|
It will be used for getaddrinfo(), for which it is difficult to maintain
|
||||||
list of required system calls (with glibc it depends on what NSS modules
|
a list of required system calls (with glibc it depends on what NSS
|
||||||
are installed and enabled on the system). */
|
modules are installed and enabled on the system). */
|
||||||
|
if (default_action != SCMP_ACT_ALLOW)
|
||||||
PRV_StartHelper();
|
PRV_StartHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = seccomp_init(level > 0 ? SCMP_ACT_KILL : SCMP_ACT_TRAP);
|
ctx = seccomp_init(default_action);
|
||||||
if (ctx == NULL)
|
if (ctx == NULL)
|
||||||
LOG_FATAL("Failed to initialize seccomp");
|
LOG_FATAL("Failed to initialize seccomp");
|
||||||
|
|
||||||
/* Add system calls that are always allowed */
|
if (default_action != SCMP_ACT_ALLOW) {
|
||||||
for (i = 0; i < (sizeof (syscalls) / sizeof (*syscalls)); i++) {
|
for (i = 0; i < sizeof (allowed) / sizeof (*allowed); i++) {
|
||||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) < 0)
|
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, allowed[i], 0) < 0)
|
||||||
|
goto add_failed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < sizeof (denied_any) / sizeof (*denied_any); i++) {
|
||||||
|
if (seccomp_rule_add(ctx, deny_action, denied_any[i], 0) < 0)
|
||||||
goto add_failed;
|
goto add_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context == SYS_MAIN_PROCESS) {
|
if (context == SYS_NTSKE_HELPER) {
|
||||||
|
for (i = 0; i < sizeof (denied_ntske) / sizeof (*denied_ntske); i++) {
|
||||||
|
if (seccomp_rule_add(ctx, deny_action, denied_ntske[i], 0) < 0)
|
||||||
|
goto add_failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (default_action != SCMP_ACT_ALLOW && context == SYS_MAIN_PROCESS) {
|
||||||
/* Allow opening sockets in selected domains */
|
/* Allow opening sockets in selected domains */
|
||||||
for (i = 0; i < sizeof (socket_domains) / sizeof (*socket_domains); i++) {
|
for (i = 0; i < sizeof (socket_domains) / sizeof (*socket_domains); i++) {
|
||||||
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
|
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
|
||||||
@@ -723,7 +777,8 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
|||||||
if (seccomp_load(ctx) < 0)
|
if (seccomp_load(ctx) < 0)
|
||||||
LOG_FATAL("Failed to load seccomp rules");
|
LOG_FATAL("Failed to load seccomp rules");
|
||||||
|
|
||||||
LOG(context == SYS_MAIN_PROCESS ? LOGS_INFO : LOGS_DEBUG, "Loaded seccomp filter");
|
LOG(context == SYS_MAIN_PROCESS ? LOGS_INFO : LOGS_DEBUG,
|
||||||
|
"Loaded seccomp filter (level %d)", level);
|
||||||
seccomp_release(ctx);
|
seccomp_release(ctx);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
. ./test.common
|
|
||||||
|
|
||||||
check_chronyd_features SCFILTER || test_skip "SCFILTER support disabled"
|
|
||||||
|
|
||||||
test_start "system call filter"
|
|
||||||
|
|
||||||
for extra_chronyd_options in "-F -1" "-F 1"; do
|
|
||||||
start_chronyd || test_fail
|
|
||||||
wait_for_sync || test_fail
|
|
||||||
stop_chronyd || test_fail
|
|
||||||
check_chronyd_messages || test_fail
|
|
||||||
check_chronyd_files || test_fail
|
|
||||||
done
|
|
||||||
|
|
||||||
test_pass
|
|
||||||
@@ -23,8 +23,11 @@ for command in \
|
|||||||
"dfreq 1.0e-3" \
|
"dfreq 1.0e-3" \
|
||||||
"doffset -0.1" \
|
"doffset -0.1" \
|
||||||
"dump" \
|
"dump" \
|
||||||
|
"offline" \
|
||||||
"local off" \
|
"local off" \
|
||||||
"local" \
|
"local" \
|
||||||
|
"online" \
|
||||||
|
"onoffline" \
|
||||||
"maxdelay $server 1e-1" \
|
"maxdelay $server 1e-1" \
|
||||||
"maxdelaydevratio $server 5.0" \
|
"maxdelaydevratio $server 5.0" \
|
||||||
"maxdelayratio $server 3.0" \
|
"maxdelayratio $server 3.0" \
|
||||||
@@ -32,9 +35,6 @@ for command in \
|
|||||||
"maxupdateskew $server 10.0" \
|
"maxupdateskew $server 10.0" \
|
||||||
"minpoll $server 10" \
|
"minpoll $server 10" \
|
||||||
"minstratum $server 1" \
|
"minstratum $server 1" \
|
||||||
"offline" \
|
|
||||||
"online" \
|
|
||||||
"onoffline" \
|
|
||||||
"polltarget $server 10" \
|
"polltarget $server 10" \
|
||||||
"refresh" \
|
"refresh" \
|
||||||
"rekey" \
|
"rekey" \
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
check_chronyd_features NTS || test_skip "NTS support disabled"
|
check_chronyd_features NTS || test_skip "NTS support disabled"
|
||||||
certtool --help &> /dev/null || test_skip "certtool missing"
|
certtool --help &> /dev/null || test_skip "certtool missing"
|
||||||
|
|
||||||
check_chronyd_features PRIVDROP && user="nobody"
|
|
||||||
|
|
||||||
test_start "NTS authentication"
|
test_start "NTS authentication"
|
||||||
|
|
||||||
cat > $TEST_DIR/cert.cfg <<EOF
|
cat > $TEST_DIR/cert.cfg <<EOF
|
||||||
@@ -14,8 +12,8 @@ cn = "chrony-nts-test"
|
|||||||
dns_name = "chrony-nts-test"
|
dns_name = "chrony-nts-test"
|
||||||
ip_address = "$server"
|
ip_address = "$server"
|
||||||
serial = 001
|
serial = 001
|
||||||
activation_date = "$(date -d '1 year ago' +'%Y-%m-%d') 00:00:00 UTC"
|
activation_date = "$[$(date '+%Y') - 1]-01-01 00:00:00 UTC"
|
||||||
expiration_date = "$(date -d '1 year' +'%Y-%m-%d') 00:00:00 UTC"
|
expiration_date = "$[$(date '+%Y') + 2]-01-01 00:00:00 UTC"
|
||||||
signing_key
|
signing_key
|
||||||
encryption_key
|
encryption_key
|
||||||
EOF
|
EOF
|
||||||
@@ -51,8 +49,6 @@ stop_chronyd || test_fail
|
|||||||
check_chronyd_messages || test_fail
|
check_chronyd_messages || test_fail
|
||||||
check_chronyd_files || test_fail
|
check_chronyd_files || test_fail
|
||||||
|
|
||||||
rm -f $TEST_LOGDIR/measurements.log
|
|
||||||
|
|
||||||
server_options="port $ntpport nts ntsport $((ntsport + 1))"
|
server_options="port $ntpport nts ntsport $((ntsport + 1))"
|
||||||
|
|
||||||
start_chronyd || test_fail
|
start_chronyd || test_fail
|
||||||
|
|||||||
24
test/system/099-scfilter
Executable file
24
test/system/099-scfilter
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
. ./test.common
|
||||||
|
|
||||||
|
check_chronyd_features SCFILTER || test_skip "SCFILTER support disabled"
|
||||||
|
|
||||||
|
test_start "system call filter in non-destructive tests"
|
||||||
|
|
||||||
|
for level in "-1" "1" "-2" "2"; do
|
||||||
|
test_message 1 1 "level $level:"
|
||||||
|
for test in 0[0-8][0-9]-*[^_]; do
|
||||||
|
test_message 2 0 "$test"
|
||||||
|
TEST_SCFILTER=$level "./$test" > /dev/null 2> /dev/null
|
||||||
|
result=$?
|
||||||
|
|
||||||
|
if [ $result != 0 ] && [ $result != 9 ] ; then
|
||||||
|
test_bad
|
||||||
|
test_fail
|
||||||
|
fi
|
||||||
|
test_ok
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
test_pass
|
||||||
24
test/system/199-scfilter
Executable file
24
test/system/199-scfilter
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
. ./test.common
|
||||||
|
|
||||||
|
check_chronyd_features SCFILTER || test_skip "SCFILTER support disabled"
|
||||||
|
|
||||||
|
test_start "system call filter in destructive tests"
|
||||||
|
|
||||||
|
for level in "-1" "1" "-2" "2"; do
|
||||||
|
test_message 1 1 "level $level:"
|
||||||
|
for test in 1[0-8][0-9]-*[^_]; do
|
||||||
|
test_message 2 0 "$test"
|
||||||
|
TEST_SCFILTER=$level "./$test" > /dev/null 2> /dev/null
|
||||||
|
result=$?
|
||||||
|
|
||||||
|
if [ $result != 0 ] && [ $result != 9 ] ; then
|
||||||
|
test_bad
|
||||||
|
test_fail
|
||||||
|
fi
|
||||||
|
test_ok
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
test_pass
|
||||||
@@ -20,6 +20,7 @@ TEST_DIR=${TEST_DIR:-$(pwd)/tmp}
|
|||||||
TEST_LIBDIR=${TEST_LIBDIR:-$TEST_DIR}
|
TEST_LIBDIR=${TEST_LIBDIR:-$TEST_DIR}
|
||||||
TEST_LOGDIR=${TEST_LOGDIR:-$TEST_DIR}
|
TEST_LOGDIR=${TEST_LOGDIR:-$TEST_DIR}
|
||||||
TEST_RUNDIR=${TEST_RUNDIR:-$TEST_DIR}
|
TEST_RUNDIR=${TEST_RUNDIR:-$TEST_DIR}
|
||||||
|
TEST_SCFILTER=${TEST_SCFILTER:-0}
|
||||||
|
|
||||||
test_start() {
|
test_start() {
|
||||||
check_chronyd_features NTP CMDMON || test_skip "NTP/CMDMON support disabled"
|
check_chronyd_features NTP CMDMON || test_skip "NTP/CMDMON support disabled"
|
||||||
@@ -228,6 +229,8 @@ generate_chrony_conf() {
|
|||||||
echo "log tempcomp rawmeasurements refclocks statistics tracking rtc"
|
echo "log tempcomp rawmeasurements refclocks statistics tracking rtc"
|
||||||
echo "logbanner 0"
|
echo "logbanner 0"
|
||||||
echo "smoothtime 100.0 0.001"
|
echo "smoothtime 100.0 0.001"
|
||||||
|
echo "leapsectz right/UTC"
|
||||||
|
echo "dscp 46"
|
||||||
|
|
||||||
echo "include /dev/null"
|
echo "include /dev/null"
|
||||||
echo "keyfile $TEST_DIR/keys"
|
echo "keyfile $TEST_DIR/keys"
|
||||||
@@ -242,6 +245,7 @@ get_chronyd_options() {
|
|||||||
echo "-l $(get_logfile)"
|
echo "-l $(get_logfile)"
|
||||||
echo "-f $(get_conffile)"
|
echo "-f $(get_conffile)"
|
||||||
echo "-u $user"
|
echo "-u $user"
|
||||||
|
echo "-F $TEST_SCFILTER"
|
||||||
echo "$extra_chronyd_options"
|
echo "$extra_chronyd_options"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,6 +260,8 @@ start_chronyd() {
|
|||||||
|
|
||||||
trap stop_chronyd EXIT
|
trap stop_chronyd EXIT
|
||||||
|
|
||||||
|
rm -f "$TEST_LOGDIR"/*.log
|
||||||
|
|
||||||
$CHRONYD_WRAPPER "$chronyd" $(get_chronyd_options) > "$TEST_DIR/chronyd.out" 2>&1
|
$CHRONYD_WRAPPER "$chronyd" $(get_chronyd_options) > "$TEST_DIR/chronyd.out" 2>&1
|
||||||
|
|
||||||
[ $? -eq 0 ] && [ -f "$pidfile" ] && ps -p "$(cat "$pidfile")" > /dev/null && test_ok || test_error
|
[ $? -eq 0 ] && [ -f "$pidfile" ] && ps -p "$(cat "$pidfile")" > /dev/null && test_ok || test_error
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Miroslav Lichvar 2016
|
* Copyright (C) Miroslav Lichvar 2016, 2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
* Copyright (C) Miroslav Lichvar 2017-2018
|
* Copyright (C) Miroslav Lichvar 2017-2018, 2021
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of version 2 of the GNU General Public License as
|
* it under the terms of version 2 of the GNU General Public License as
|
||||||
@@ -151,7 +151,7 @@ test_unit(void)
|
|||||||
|
|
||||||
ts.tv_sec = 1;
|
ts.tv_sec = 1;
|
||||||
ts.tv_nsec = 500000000;
|
ts.tv_nsec = 500000000;
|
||||||
TEST_CHECK(UTI_TimespecToDouble(&ts) == 1.5);
|
TEST_CHECK(fabs(UTI_TimespecToDouble(&ts) - 1.5) < 1.0e-15);
|
||||||
|
|
||||||
UTI_DoubleToTimespec(2.75, &ts);
|
UTI_DoubleToTimespec(2.75, &ts);
|
||||||
TEST_CHECK(ts.tv_sec == 2);
|
TEST_CHECK(ts.tv_sec == 2);
|
||||||
@@ -171,7 +171,7 @@ test_unit(void)
|
|||||||
|
|
||||||
tv.tv_sec = 1;
|
tv.tv_sec = 1;
|
||||||
tv.tv_usec = 500000;
|
tv.tv_usec = 500000;
|
||||||
TEST_CHECK(UTI_TimevalToDouble(&tv) == 1.5);
|
TEST_CHECK(fabs(UTI_TimevalToDouble(&tv) - 1.5) < 1.0e-15);
|
||||||
|
|
||||||
UTI_DoubleToTimeval(2.75, &tv);
|
UTI_DoubleToTimeval(2.75, &tv);
|
||||||
TEST_CHECK(tv.tv_sec == 2);
|
TEST_CHECK(tv.tv_sec == 2);
|
||||||
@@ -267,7 +267,7 @@ test_unit(void)
|
|||||||
UTI_DiffTimespecs(&ts3, &ts, &ts2);
|
UTI_DiffTimespecs(&ts3, &ts, &ts2);
|
||||||
TEST_CHECK(ts3.tv_sec == 0);
|
TEST_CHECK(ts3.tv_sec == 0);
|
||||||
TEST_CHECK(ts3.tv_nsec == 500000000);
|
TEST_CHECK(ts3.tv_nsec == 500000000);
|
||||||
TEST_CHECK(UTI_DiffTimespecsToDouble(&ts, &ts2) == 0.5);
|
TEST_CHECK(fabs(UTI_DiffTimespecsToDouble(&ts, &ts2) - 0.5) < 1.0e-15);
|
||||||
|
|
||||||
ts.tv_sec = 2;
|
ts.tv_sec = 2;
|
||||||
ts.tv_nsec = 250000000;
|
ts.tv_nsec = 250000000;
|
||||||
@@ -276,7 +276,7 @@ test_unit(void)
|
|||||||
UTI_DiffTimespecs(&ts3, &ts, &ts2);
|
UTI_DiffTimespecs(&ts3, &ts, &ts2);
|
||||||
TEST_CHECK(ts3.tv_sec == -2);
|
TEST_CHECK(ts3.tv_sec == -2);
|
||||||
TEST_CHECK(ts3.tv_nsec == 500000000);
|
TEST_CHECK(ts3.tv_nsec == 500000000);
|
||||||
TEST_CHECK(UTI_DiffTimespecsToDouble(&ts, &ts2) == -1.5);
|
TEST_CHECK(fabs(UTI_DiffTimespecsToDouble(&ts, &ts2) - -1.5) < 1.0e-15);
|
||||||
|
|
||||||
ts.tv_sec = 2;
|
ts.tv_sec = 2;
|
||||||
ts.tv_nsec = 250000000;
|
ts.tv_nsec = 250000000;
|
||||||
@@ -471,7 +471,7 @@ test_unit(void)
|
|||||||
ts2.tv_sec = 4;
|
ts2.tv_sec = 4;
|
||||||
ts2.tv_nsec = 250000000;
|
ts2.tv_nsec = 250000000;
|
||||||
UTI_AdjustTimespec(&ts, &ts2, &ts3, &x, 2.0, -5.0);
|
UTI_AdjustTimespec(&ts, &ts2, &ts3, &x, 2.0, -5.0);
|
||||||
TEST_CHECK(x == 6.5);
|
TEST_CHECK(fabs(x - 6.5) < 1.0e-15);
|
||||||
TEST_CHECK(ts3.tv_sec == 10);
|
TEST_CHECK(ts3.tv_sec == 10);
|
||||||
TEST_CHECK(ts3.tv_nsec == 0);
|
TEST_CHECK(ts3.tv_nsec == 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user