mirror of
https://gitlab.com/chrony/chrony.git
synced 2026-03-11 00:59:38 -04:00
sys: add OpenBSD support
Add OpenBSD support, including pledge(2) support by implementing SYS_EnableSystemCallFilter(). This commit depends on the addition of AdjustFreq() privops and the addtion of invoking SYS_EnableSystemCallFilter() from PRV_StartHelper(). Only system call filter levels on/off' are supported. Setting level to 0 disables the filter and setting it to 1 enables it. Update the documentation to reflect that OpenBSD supports: - the SCHED_FIFO real-time scheduler (option -P) - locking chronyd into memory (option -m) - reload sample history of servers and ref clocks (option -r) - forking into two process when run as non-root user (option -u) - maxdrift/maxslewrate of 100000.
This commit is contained in:
committed by
Miroslav Lichvar
parent
9a57ef8dbf
commit
4ddc6b334d
6
README
6
README
@@ -27,9 +27,9 @@ operating parameters whilst it is running.
|
|||||||
What will chrony run on?
|
What will chrony run on?
|
||||||
========================
|
========================
|
||||||
|
|
||||||
The software is known to work on Linux, FreeBSD, NetBSD, macOS and
|
The software is known to work on Linux, FreeBSD, NetBSD, OpenBSD, macOS,
|
||||||
illumos. Closely related systems may work too. Any other system will
|
and illumos. Closely related systems may work too. Any other system
|
||||||
likely require a porting exercise.
|
will likely require a porting exercise.
|
||||||
|
|
||||||
How do I set it up?
|
How do I set it up?
|
||||||
===================
|
===================
|
||||||
|
|||||||
19
configure
vendored
19
configure
vendored
@@ -234,6 +234,7 @@ try_libcap=-1
|
|||||||
try_clockctl=0
|
try_clockctl=0
|
||||||
feat_scfilter=0
|
feat_scfilter=0
|
||||||
try_seccomp=-1
|
try_seccomp=-1
|
||||||
|
try_pledge=0
|
||||||
priv_ops=""
|
priv_ops=""
|
||||||
feat_ipv6=1
|
feat_ipv6=1
|
||||||
feat_phc=1
|
feat_phc=1
|
||||||
@@ -447,6 +448,18 @@ case $OPERATINGSYSTEM in
|
|||||||
add_def NETBSD
|
add_def NETBSD
|
||||||
echo "Configuring for $SYSTEM"
|
echo "Configuring for $SYSTEM"
|
||||||
;;
|
;;
|
||||||
|
OpenBSD)
|
||||||
|
EXTRA_OBJECTS="sys_generic.o sys_openbsd.o sys_posix.o"
|
||||||
|
try_setsched=1
|
||||||
|
try_lockmem=1
|
||||||
|
try_pledge=1
|
||||||
|
add_def OPENBSD
|
||||||
|
if [ $feat_droproot = "1" ]; then
|
||||||
|
add_def FEAT_PRIVDROP
|
||||||
|
priv_ops="ADJUSTTIME ADJUSTFREQ SETTIME"
|
||||||
|
fi
|
||||||
|
echo "Configuring for $SYSTEM"
|
||||||
|
;;
|
||||||
Darwin)
|
Darwin)
|
||||||
EXTRA_OBJECTS="sys_macosx.o"
|
EXTRA_OBJECTS="sys_macosx.o"
|
||||||
LIBS="$LIBS -lresolv"
|
LIBS="$LIBS -lresolv"
|
||||||
@@ -812,6 +825,12 @@ then
|
|||||||
EXTRA_OBJECTS="$EXTRA_OBJECTS sys_linux_scmp.o"
|
EXTRA_OBJECTS="$EXTRA_OBJECTS sys_linux_scmp.o"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ $feat_scfilter = "1" ] && [ $try_pledge = "1" ] && \
|
||||||
|
test_code 'pledge()' 'unistd.h' '' '' 'pledge("stdio", NULL);'
|
||||||
|
then
|
||||||
|
add_def FEAT_SCFILTER
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "x$priv_ops" != "x" ]; then
|
if [ "x$priv_ops" != "x" ]; then
|
||||||
EXTRA_OBJECTS="$EXTRA_OBJECTS privops.o"
|
EXTRA_OBJECTS="$EXTRA_OBJECTS privops.o"
|
||||||
add_def PRIVOPS_HELPER
|
add_def PRIVOPS_HELPER
|
||||||
|
|||||||
@@ -1449,8 +1449,8 @@ for a high quality clock using a temperature compensated crystal oscillator.
|
|||||||
This directive specifies the maximum assumed drift (frequency error) of the
|
This directive specifies the maximum assumed drift (frequency error) of the
|
||||||
system clock. It limits the frequency adjustment that *chronyd* is allowed to
|
system clock. It limits the frequency adjustment that *chronyd* is allowed to
|
||||||
use to correct the measured drift. It is an additional limit to the maximum
|
use to correct the measured drift. It is an additional limit to the maximum
|
||||||
adjustment that can be set by the system driver (100000 ppm on Linux, 500 ppm
|
adjustment that can be set by the system driver (100000 ppm on Linux and
|
||||||
on FreeBSD, NetBSD, and macOS 10.13+, 32500 ppm on illumos).
|
OpenBSD, 500 ppm on FreeBSD, NetBSD, and macOS 10.13+, 32500 ppm on illumos).
|
||||||
+
|
+
|
||||||
By default, the maximum assumed drift is 500000 ppm, i.e. the adjustment is
|
By default, the maximum assumed drift is 500000 ppm, i.e. the adjustment is
|
||||||
limited by the system driver rather than this directive.
|
limited by the system driver rather than this directive.
|
||||||
@@ -1487,10 +1487,10 @@ is effective only on systems where *chronyd* is able to control the rate (i.e.
|
|||||||
all supported systems with the exception of macOS 12 or earlier).
|
all supported systems with the exception of macOS 12 or earlier).
|
||||||
+
|
+
|
||||||
For each system there is a maximum frequency offset of the clock that can be set
|
For each system there is a maximum frequency offset of the clock that can be set
|
||||||
by the driver. On Linux it is 100000 ppm, on FreeBSD, NetBSD and macOS 10.13+ it
|
by the driver. On Linux and OpenBSD it is 100000 ppm, on FreeBSD, NetBSD and
|
||||||
is 5000 ppm, and on illumos it is 32500 ppm. Also, due to a kernel limitation,
|
macOS 10.13+ it is 5000 ppm, on illumos it is 32500 ppm. Also, due to a kernel
|
||||||
setting *maxslewrate* on FreeBSD, NetBSD, macOS 10.13+ to a value between 500
|
limitation, setting *maxslewrate* on FreeBSD, NetBSD, macOS 10.13+ to a value
|
||||||
ppm and 5000 ppm will effectively set it to 500 ppm.
|
between 500 ppm and 5000 ppm will effectively set it to 500 ppm.
|
||||||
+
|
+
|
||||||
By default, the maximum slew rate is set to 83333.333 ppm (one twelfth).
|
By default, the maximum slew rate is set to 83333.333 ppm (one twelfth).
|
||||||
|
|
||||||
@@ -2988,7 +2988,7 @@ file when the <<chronyc.adoc#rekey,*rekey*>> command is issued by *chronyc*).
|
|||||||
[[lock_all]]*lock_all*::
|
[[lock_all]]*lock_all*::
|
||||||
The *lock_all* directive will lock the *chronyd* process into RAM so that it
|
The *lock_all* directive will lock the *chronyd* process into RAM so that it
|
||||||
will never be paged out. This can result in lower and more consistent latency.
|
will never be paged out. This can result in lower and more consistent latency.
|
||||||
The directive is supported on Linux, FreeBSD, NetBSD, and illumos.
|
The directive is supported on Linux, FreeBSD, NetBSD, OpenBSD, and illumos.
|
||||||
|
|
||||||
[[pidfile]]*pidfile* _file_::
|
[[pidfile]]*pidfile* _file_::
|
||||||
Unless *chronyd* is started with the *-Q* option, it writes its process ID
|
Unless *chronyd* is started with the *-Q* option, it writes its process ID
|
||||||
@@ -3039,11 +3039,11 @@ accepted NTP-over-PTP messages. Messages from other domains are ignored.
|
|||||||
The default is 123, the minimum is 0, and the maximum is 255.
|
The default is 123, the minimum is 0, and the maximum is 255.
|
||||||
|
|
||||||
[[sched_priority]]*sched_priority* _priority_::
|
[[sched_priority]]*sched_priority* _priority_::
|
||||||
On Linux, FreeBSD, NetBSD, and illumos, the *sched_priority* directive will
|
On Linux, FreeBSD, NetBSD, OpenBSD, and illumos, the *sched_priority* directive
|
||||||
select the SCHED_FIFO real-time scheduler at the specified priority (which must
|
will select the SCHED_FIFO real-time scheduler at the specified priority (which
|
||||||
be between 0 and 100). On macOS, this option must have either a value of 0 (the
|
must be between 0 and 100). On macOS, this option must have either a value of 0
|
||||||
default) to disable the thread time constraint policy or 1 for the policy to be
|
(the default) to disable the thread time constraint policy or 1 for the policy
|
||||||
enabled.
|
to be enabled.
|
||||||
+
|
+
|
||||||
On systems other than macOS, this directive uses the *pthread_setschedparam()*
|
On systems other than macOS, this directive uses the *pthread_setschedparam()*
|
||||||
system call to instruct the kernel to use the SCHED_FIFO first-in, first-out
|
system call to instruct the kernel to use the SCHED_FIFO first-in, first-out
|
||||||
@@ -3065,9 +3065,9 @@ The *user* directive sets the name of the system user to which *chronyd* will
|
|||||||
switch after start in order to drop root privileges.
|
switch after start in order to drop root privileges.
|
||||||
+
|
+
|
||||||
On Linux, *chronyd* needs to be compiled with support for the *libcap* library.
|
On Linux, *chronyd* needs to be compiled with support for the *libcap* library.
|
||||||
On macOS, FreeBSD, NetBSD and illumos *chronyd* forks into two processes.
|
On macOS, FreeBSD, NetBSD, OpenBSD, and illumos *chronyd* forks into two
|
||||||
The child process retains root privileges, but can only perform a very limited
|
processes. The child process retains root privileges, but can only perform a
|
||||||
range of privileged system calls on behalf of the parent.
|
very limited range of privileged system calls on behalf of the parent.
|
||||||
+
|
+
|
||||||
The compiled-in default value is _@DEFAULT_USER@_.
|
The compiled-in default value is _@DEFAULT_USER@_.
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ directive in the configuration file. This option is useful if you want to stop
|
|||||||
and restart *chronyd* briefly for any reason, e.g. to install a new version.
|
and restart *chronyd* briefly for any reason, e.g. to install a new version.
|
||||||
However, it should be used only on systems where the kernel can maintain clock
|
However, it should be used only on systems where the kernel can maintain clock
|
||||||
compensation whilst not under *chronyd*'s control (i.e. Linux, FreeBSD, NetBSD,
|
compensation whilst not under *chronyd*'s control (i.e. Linux, FreeBSD, NetBSD,
|
||||||
illumos, and macOS 10.13 or later).
|
OpenBSD, illumos, and macOS 10.13 or later).
|
||||||
|
|
||||||
*-R*::
|
*-R*::
|
||||||
When this option is used, the <<chrony.conf.adoc#initstepslew,*initstepslew*>>
|
When this option is used, the <<chrony.conf.adoc#initstepslew,*initstepslew*>>
|
||||||
@@ -143,9 +143,9 @@ after start in order to drop root privileges. It overrides the
|
|||||||
_@DEFAULT_USER@_.
|
_@DEFAULT_USER@_.
|
||||||
+
|
+
|
||||||
On Linux, *chronyd* needs to be compiled with support for the *libcap* library.
|
On Linux, *chronyd* needs to be compiled with support for the *libcap* library.
|
||||||
On macOS, FreeBSD, NetBSD, and illumos *chronyd* forks into two processes.
|
On macOS, FreeBSD, NetBSD, OpenBSD, and illumos *chronyd* forks into two
|
||||||
The child process retains root privileges, but can only perform a very limited
|
processes. The child process retains root privileges, but can only perform a
|
||||||
range of privileged system calls on behalf of the parent.
|
very limited range of privileged system calls on behalf of the parent.
|
||||||
|
|
||||||
*-U*::
|
*-U*::
|
||||||
This option disables a check for root privileges to allow *chronyd* to be
|
This option disables a check for root privileges to allow *chronyd* to be
|
||||||
@@ -159,21 +159,22 @@ specific directives.
|
|||||||
|
|
||||||
*-F* _level_::
|
*-F* _level_::
|
||||||
This option configures system call filters loaded by *chronyd* processes if it
|
This option configures system call filters loaded by *chronyd* processes if it
|
||||||
was compiled with support for the Linux secure computing (seccomp) facility.
|
was compiled with support for the Linux secure computing (seccomp) facility or
|
||||||
Three levels are defined: 0, 1, 2. The filters are disabled at level 0. At
|
OpenBSD pledge. For Linux three levels are defined: 0, 1, 2, for OpenBSD two
|
||||||
levels 1 and 2, *chronyd* will be killed if it makes a system call which is
|
levels: 0, 1. The filters are disabled at level 0. On Linux at levels 1 and 2
|
||||||
blocked by the filters. The level can be specified as a negative number to
|
and on OpenBSD at level 1, *chronyd* will be killed if it makes a system call
|
||||||
trigger the SIGSYS signal instead of SIGKILL, which can be useful for
|
which is blocked by the filters. On Linux the level can be specified as a
|
||||||
debugging. The default value is 0.
|
negative number to trigger the SIGSYS signal instead of SIGKILL, which can be
|
||||||
|
useful for debugging. The default value is 0.
|
||||||
+
|
+
|
||||||
At level 1, the filters allow only selected system calls that are normally
|
On Linux at level 1, the filters allow only selected system calls that are
|
||||||
expected to be made by *chronyd*. Other system calls are blocked. This level is
|
normally expected to be made by *chronyd*. Other system calls are blocked.
|
||||||
recommended only if it is known to work on the version of the system where
|
This level is recommended only if it is known to work on the version of the
|
||||||
*chrony* is installed. The filters need to allow also system calls made by
|
system where *chrony* is installed. The filters need to allow also system
|
||||||
libraries that *chronyd* is using (e.g. libc), but different versions or
|
calls made by libraries that *chronyd* is using (e.g. libc), but different
|
||||||
implementations of the libraries might make different system calls. If the
|
versions or implementations of the libraries might make different system calls.
|
||||||
filters are missing a system call, *chronyd* could be killed even in normal
|
If the filters are missing a system call, *chronyd* could be killed even in
|
||||||
operation.
|
normal operation.
|
||||||
+
|
+
|
||||||
At level 2, the filters block only a small number of specific system calls
|
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
|
(e.g. fork and exec). This approach should avoid false positives, but the
|
||||||
@@ -183,15 +184,15 @@ limited.
|
|||||||
The filters cannot be enabled with the *mailonchange* directive.
|
The filters cannot be enabled with the *mailonchange* directive.
|
||||||
|
|
||||||
*-P* _priority_::
|
*-P* _priority_::
|
||||||
On Linux, FreeBSD, NetBSD, and illumos this option will select the SCHED_FIFO
|
On Linux, FreeBSD, NetBSD, OpenBSD, and illumos this option will select the
|
||||||
real-time scheduler at the specified priority (which must be between 0 and
|
SCHED_FIFO real-time scheduler at the specified priority (which must be
|
||||||
100). On macOS, this option must have either a value of 0 to disable the thread
|
between 0 and 100). On macOS, this option must have either a value of 0 to
|
||||||
time constraint policy or 1 for the policy to be enabled. Other systems do not
|
disable the thread time constraint policy or 1 for the policy to be enabled.
|
||||||
support this option. The default value is 0.
|
Other systems do not support this option. The default value is 0.
|
||||||
|
|
||||||
*-m*::
|
*-m*::
|
||||||
This option will lock *chronyd* into RAM so that it will never be paged out.
|
This option will lock *chronyd* into RAM so that it will never be paged out.
|
||||||
This mode is only supported on Linux, FreeBSD, NetBSD, and illumos.
|
This mode is only supported on Linux, FreeBSD, NetBSD, OpenBSD, and illumos.
|
||||||
|
|
||||||
*-x*::
|
*-x*::
|
||||||
This option disables the control of the system clock. *chronyd* will not try to
|
This option disables the control of the system clock. *chronyd* will not try to
|
||||||
|
|||||||
11
sys.c
11
sys.c
@@ -42,6 +42,9 @@
|
|||||||
#elif defined(NETBSD) || defined(FREEBSD)
|
#elif defined(NETBSD) || defined(FREEBSD)
|
||||||
#include "sys_netbsd.h"
|
#include "sys_netbsd.h"
|
||||||
#include "sys_posix.h"
|
#include "sys_posix.h"
|
||||||
|
#elif defined(OPENBSD)
|
||||||
|
#include "sys_openbsd.h"
|
||||||
|
#include "sys_posix.h"
|
||||||
#elif defined(MACOSX)
|
#elif defined(MACOSX)
|
||||||
#include "sys_macosx.h"
|
#include "sys_macosx.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -66,6 +69,8 @@ SYS_Initialise(int clock_control)
|
|||||||
SYS_Solaris_Initialise();
|
SYS_Solaris_Initialise();
|
||||||
#elif defined(NETBSD) || defined(FREEBSD)
|
#elif defined(NETBSD) || defined(FREEBSD)
|
||||||
SYS_NetBSD_Initialise();
|
SYS_NetBSD_Initialise();
|
||||||
|
#elif defined(OPENBSD)
|
||||||
|
SYS_OpenBSD_Initialise();
|
||||||
#elif defined(MACOSX)
|
#elif defined(MACOSX)
|
||||||
SYS_MacOSX_Initialise();
|
SYS_MacOSX_Initialise();
|
||||||
#else
|
#else
|
||||||
@@ -88,6 +93,8 @@ SYS_Finalise(void)
|
|||||||
SYS_Solaris_Finalise();
|
SYS_Solaris_Finalise();
|
||||||
#elif defined(NETBSD) || defined(FREEBSD)
|
#elif defined(NETBSD) || defined(FREEBSD)
|
||||||
SYS_NetBSD_Finalise();
|
SYS_NetBSD_Finalise();
|
||||||
|
#elif defined(OPENBSD)
|
||||||
|
SYS_OpenBSD_Finalise();
|
||||||
#elif defined(MACOSX)
|
#elif defined(MACOSX)
|
||||||
SYS_MacOSX_Finalise();
|
SYS_MacOSX_Finalise();
|
||||||
#else
|
#else
|
||||||
@@ -105,6 +112,8 @@ void SYS_DropRoot(uid_t uid, gid_t gid, SYS_ProcessContext context)
|
|||||||
SYS_Solaris_DropRoot(uid, gid, context);
|
SYS_Solaris_DropRoot(uid, gid, context);
|
||||||
#elif (defined(NETBSD) || defined(FREEBSD)) && defined(FEAT_PRIVDROP)
|
#elif (defined(NETBSD) || defined(FREEBSD)) && defined(FEAT_PRIVDROP)
|
||||||
SYS_NetBSD_DropRoot(uid, gid, context, !null_driver);
|
SYS_NetBSD_DropRoot(uid, gid, context, !null_driver);
|
||||||
|
#elif defined(OPENBSD) && defined(FEAT_PRIVDROP)
|
||||||
|
SYS_OpenBSD_DropRoot(uid, gid, context, !null_driver);
|
||||||
#elif defined(MACOSX) && defined(FEAT_PRIVDROP)
|
#elif defined(MACOSX) && defined(FEAT_PRIVDROP)
|
||||||
SYS_MacOSX_DropRoot(uid, gid, context);
|
SYS_MacOSX_DropRoot(uid, gid, context);
|
||||||
#else
|
#else
|
||||||
@@ -118,6 +127,8 @@ void SYS_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
|||||||
{
|
{
|
||||||
#if defined(LINUX) && defined(FEAT_SCFILTER)
|
#if defined(LINUX) && defined(FEAT_SCFILTER)
|
||||||
SYS_Linux_EnableSystemCallFilter(level, context);
|
SYS_Linux_EnableSystemCallFilter(level, context);
|
||||||
|
#elif defined(OPENBSD) && defined(FEAT_SCFILTER)
|
||||||
|
SYS_OpenBSD_EnableSystemCallFilter(level, context);
|
||||||
#else
|
#else
|
||||||
LOG_FATAL("system call filter not supported");
|
LOG_FATAL("system call filter not supported");
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
281
sys_openbsd.c
Normal file
281
sys_openbsd.c
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
/*
|
||||||
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (C) Richard P. Curnow 1997-2001
|
||||||
|
* Copyright (C) J. Hannken-Illjes 2001
|
||||||
|
* Copyright (C) Miroslav Lichvar 2015
|
||||||
|
* Copyright (C) Shaun Ren 2021
|
||||||
|
* Copyright (C) Thomas Kupper 2026
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Driver file for the OpenBSD operating system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "sysincl.h"
|
||||||
|
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
|
#include "sys_generic.h"
|
||||||
|
#include "sys_openbsd.h"
|
||||||
|
#include "conf.h"
|
||||||
|
#include "local.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "privops.h"
|
||||||
|
#include "sched.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/* The OpenBSD kernel supports a maximum value of 500000 ppm.
|
||||||
|
To avoid extending the range that would need to be tested, use
|
||||||
|
the same maximum as on Linux.
|
||||||
|
|
||||||
|
Maximum frequency offset (in ppm) */
|
||||||
|
#define MAX_FREQ 100000.0
|
||||||
|
|
||||||
|
/* RTC synchronisation - once an hour */
|
||||||
|
|
||||||
|
static struct timespec last_rtc_sync;
|
||||||
|
#define RTC_SYNC_INTERVAL (60 * 60.0)
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static double
|
||||||
|
read_frequency(void)
|
||||||
|
{
|
||||||
|
int64_t freq;
|
||||||
|
|
||||||
|
if (PRV_AdjustFreq(NULL, &freq))
|
||||||
|
LOG_FATAL("adjfreq() failed");
|
||||||
|
|
||||||
|
return (double)-freq / (1000LL << 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static double
|
||||||
|
set_frequency(double freq_ppm)
|
||||||
|
{
|
||||||
|
int64_t freq;
|
||||||
|
|
||||||
|
freq = -freq_ppm * (1000LL << 32);
|
||||||
|
if (PRV_AdjustFreq(&freq, NULL))
|
||||||
|
LOG_FATAL("adjfreq() failed");
|
||||||
|
|
||||||
|
return read_frequency();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
synchronise_rtc(void)
|
||||||
|
{
|
||||||
|
struct timespec ts, new_ts;
|
||||||
|
double err;
|
||||||
|
|
||||||
|
LCL_ReadRawTime(&ts);
|
||||||
|
|
||||||
|
if (PRV_SetTime(CLOCK_REALTIME, &ts) < 0) {
|
||||||
|
DEBUG_LOG("clock_settime() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LCL_ReadRawTime(&new_ts);
|
||||||
|
err = UTI_DiffTimespecsToDouble(&new_ts, &ts);
|
||||||
|
|
||||||
|
lcl_InvokeDispersionNotifyHandlers(fabs(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_sync_status(int synchronised, double est_error, double max_error)
|
||||||
|
{
|
||||||
|
double rtc_sync_elapsed;
|
||||||
|
struct timespec now;
|
||||||
|
|
||||||
|
if (!synchronised || !CNF_GetRtcSync())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SCH_GetLastEventTime(NULL, NULL, &now);
|
||||||
|
rtc_sync_elapsed = UTI_DiffTimespecsToDouble(&now, &last_rtc_sync);
|
||||||
|
if (fabs(rtc_sync_elapsed) >= RTC_SYNC_INTERVAL) {
|
||||||
|
synchronise_rtc();
|
||||||
|
last_rtc_sync = now;
|
||||||
|
DEBUG_LOG("rtc synchronised");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static struct clockinfo
|
||||||
|
get_clockinfo(void)
|
||||||
|
{
|
||||||
|
struct clockinfo cinfo;
|
||||||
|
size_t cinfo_len;
|
||||||
|
int mib[2];
|
||||||
|
|
||||||
|
cinfo_len = sizeof (cinfo);
|
||||||
|
mib[0] = CTL_KERN;
|
||||||
|
mib[1] = KERN_CLOCKRATE;
|
||||||
|
|
||||||
|
if (sysctl(mib, 2, &cinfo, &cinfo_len, NULL, 0) < 0)
|
||||||
|
LOG_FATAL("sysctl() failed");
|
||||||
|
|
||||||
|
return cinfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
static void
|
||||||
|
reset_adjtime_offset(void)
|
||||||
|
{
|
||||||
|
struct timeval delta;
|
||||||
|
|
||||||
|
memset(&delta, 0, sizeof (delta));
|
||||||
|
|
||||||
|
if (PRV_AdjustTime(&delta, NULL))
|
||||||
|
LOG_FATAL("adjtime() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
/* PRV_SetTime() uses clock_settime() to set the system time.
|
||||||
|
clock_setsetime() on OpenBSD is not pledged but
|
||||||
|
settimeofday() is. Override clock_settime() here for
|
||||||
|
OpenBSD and call settimeofday() from it. */
|
||||||
|
|
||||||
|
int
|
||||||
|
clock_settime(clockid_t clock, const struct timespec *now)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
if (clock != CLOCK_REALTIME)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
UTI_TimespecToTimeval(now, &tv);
|
||||||
|
|
||||||
|
return settimeofday(&tv, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
SYS_OpenBSD_Initialise(void)
|
||||||
|
{
|
||||||
|
struct clockinfo cinfo;
|
||||||
|
|
||||||
|
cinfo = get_clockinfo();
|
||||||
|
reset_adjtime_offset();
|
||||||
|
|
||||||
|
LCL_ReadRawTime(&last_rtc_sync);
|
||||||
|
|
||||||
|
SYS_Generic_CompleteFreqDriver(MAX_FREQ, 1.0 / cinfo.hz,
|
||||||
|
read_frequency, set_frequency, NULL,
|
||||||
|
0.0, 0.0,
|
||||||
|
NULL, NULL,
|
||||||
|
NULL, set_sync_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
void
|
||||||
|
SYS_OpenBSD_Finalise(void)
|
||||||
|
{
|
||||||
|
SYS_Generic_Finalise();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
#ifdef FEAT_PRIVDROP
|
||||||
|
void
|
||||||
|
SYS_OpenBSD_DropRoot(uid_t uid, gid_t gid, SYS_ProcessContext context, int clock_control)
|
||||||
|
{
|
||||||
|
if (context == SYS_MAIN_PROCESS)
|
||||||
|
PRV_StartHelper();
|
||||||
|
|
||||||
|
UTI_DropRoot(uid, gid);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
|
#ifdef FEAT_SCFILTER
|
||||||
|
void
|
||||||
|
SYS_OpenBSD_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
||||||
|
{
|
||||||
|
/* If level == 0, SYS_EnableSystemCallFilter() is not called. Therefore
|
||||||
|
only a value of 1 is valid here. */
|
||||||
|
if (level != 1 && context == SYS_MAIN_PROCESS)
|
||||||
|
/* Only log/fatal once in the main process, the child processes will be
|
||||||
|
terminated too as a result */
|
||||||
|
LOG_FATAL("Unsupported filter level");
|
||||||
|
|
||||||
|
if (context == SYS_MAIN_PROCESS) {
|
||||||
|
/* stdio => allow libc stdio calls
|
||||||
|
{r,w,c}path => allow read/write/change config, drift file, etc
|
||||||
|
inet => allow connections to/from internet
|
||||||
|
unix => allow handling unix sockets
|
||||||
|
dns => allow DNS resolution
|
||||||
|
sendfd => allow send fd to nts_ke helper thread. In
|
||||||
|
NKS_Initialize() open_socket() -> accept_connection()
|
||||||
|
settime => allow set time if system call filter is enabled and user is root */
|
||||||
|
const char **certs, **keys;
|
||||||
|
|
||||||
|
if (CNF_GetNtsServerCertAndKeyFiles(&certs, &keys) > 0 &&
|
||||||
|
CNF_GetNtsServerProcesses() > 0) {
|
||||||
|
/* NTS-KE helper(s) will be forked, the 'sendfd' promise is necessary */
|
||||||
|
if (geteuid() == 0) {
|
||||||
|
/* Running as root, in addition settime pledge promise needed */
|
||||||
|
if (pledge("stdio rpath wpath cpath inet unix dns sendfd settime", NULL) < 0)
|
||||||
|
LOG_FATAL("pledge() failed");
|
||||||
|
} else {
|
||||||
|
if (pledge("stdio rpath wpath cpath inet unix dns sendfd", NULL) < 0)
|
||||||
|
LOG_FATAL("pledge() failed");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No NTS-KE helper(s) will be forked, no need to set 'sendfd' promise */
|
||||||
|
if (geteuid() == 0) {
|
||||||
|
/* Running as root, in addition settime pledge promise needed */
|
||||||
|
if (pledge("stdio rpath wpath cpath inet unix dns settime", NULL) < 0)
|
||||||
|
LOG_FATAL("pledge() failed");
|
||||||
|
} else {
|
||||||
|
if (pledge("stdio rpath wpath cpath inet unix dns", NULL) < 0)
|
||||||
|
LOG_FATAL("pledge() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (context == SYS_PRIVOPS_HELPER) {
|
||||||
|
/* stdio => allow libc stdio calls
|
||||||
|
settime => allow set/adjust time */
|
||||||
|
if (pledge("stdio settime", NULL) < 0)
|
||||||
|
LOG_FATAL("pledge() failed");
|
||||||
|
} else if (context == SYS_NTSKE_HELPER) {
|
||||||
|
/* stdio => allow libc stdio calls
|
||||||
|
recvfd => allow receiving fd from main process. In run_helper()
|
||||||
|
-> handle_helper_request() */
|
||||||
|
if (pledge("stdio recvfd", NULL) < 0)
|
||||||
|
LOG_FATAL("pledge() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG(context == SYS_MAIN_PROCESS ? LOGS_INFO : LOGS_DEBUG, "Loaded pledge filter");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
41
sys_openbsd.h
Normal file
41
sys_openbsd.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
||||||
|
|
||||||
|
**********************************************************************
|
||||||
|
* Copyright (C) Shaun Ren 2021
|
||||||
|
* Copyright (C) Thomas Kupper 2026
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
**********************************************************************
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Header file for OpenBSD driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GOT_SYS_OPENBSD_H
|
||||||
|
#define GOT_SYS_OPENBSD_H
|
||||||
|
|
||||||
|
#include "sys.h"
|
||||||
|
|
||||||
|
void SYS_OpenBSD_Initialise(void);
|
||||||
|
|
||||||
|
void SYS_OpenBSD_Finalise(void);
|
||||||
|
|
||||||
|
void SYS_OpenBSD_DropRoot(uid_t uid, gid_t gid, SYS_ProcessContext context, int clock_control);
|
||||||
|
|
||||||
|
void SYS_OpenBSD_EnableSystemCallFilter(int level, SYS_ProcessContext context);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -8,7 +8,21 @@ check_chronyd_features SCFILTER || test_skip "SCFILTER support disabled"
|
|||||||
|
|
||||||
test_start "system call filter in non-destructive tests"
|
test_start "system call filter in non-destructive tests"
|
||||||
|
|
||||||
for level in 1 2 -1 -2; do
|
os_name=$(uname -s)
|
||||||
|
case "$os_name" in
|
||||||
|
OpenBSD)
|
||||||
|
supported_levels=1
|
||||||
|
;;
|
||||||
|
Linux)
|
||||||
|
supported_levels="1 2 -1 -2"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
test_message 1 1 "unsupported OS $os_name"
|
||||||
|
test_fail
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for level in $supported_levels; do
|
||||||
test_message 1 1 "level $level:"
|
test_message 1 1 "level $level:"
|
||||||
for test in 0[0-8][0-9]-*[^_]; do
|
for test in 0[0-8][0-9]-*[^_]; do
|
||||||
test_message 2 0 "$test"
|
test_message 2 0 "$test"
|
||||||
|
|||||||
@@ -8,7 +8,21 @@ check_chronyd_features SCFILTER || test_skip "SCFILTER support disabled"
|
|||||||
|
|
||||||
test_start "system call filter in destructive tests"
|
test_start "system call filter in destructive tests"
|
||||||
|
|
||||||
for level in 1 2 -1 -2; do
|
os_name="$(uname -s)"
|
||||||
|
case $os_name in
|
||||||
|
OpenBSD)
|
||||||
|
supported_levels=1
|
||||||
|
;;
|
||||||
|
Linux)
|
||||||
|
supported_levels="1 2 -1 -2"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
test_message 1 1 "unsupported OS $os_name"
|
||||||
|
test_fail
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for level in $supported_levels; do
|
||||||
test_message 1 1 "level $level:"
|
test_message 1 1 "level $level:"
|
||||||
for test in 1[0-8][0-9]-*[^_]; do
|
for test in 1[0-8][0-9]-*[^_]; do
|
||||||
test_message 2 0 "$test"
|
test_message 2 0 "$test"
|
||||||
|
|||||||
Reference in New Issue
Block a user