mirror of
https://gitlab.com/chrony/chrony.git
synced 2026-03-10 16:49: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?
|
||||
========================
|
||||
|
||||
The software is known to work on Linux, FreeBSD, NetBSD, macOS and
|
||||
illumos. Closely related systems may work too. Any other system will
|
||||
likely require a porting exercise.
|
||||
The software is known to work on Linux, FreeBSD, NetBSD, OpenBSD, macOS,
|
||||
and illumos. Closely related systems may work too. Any other system
|
||||
will likely require a porting exercise.
|
||||
|
||||
How do I set it up?
|
||||
===================
|
||||
|
||||
19
configure
vendored
19
configure
vendored
@@ -234,6 +234,7 @@ try_libcap=-1
|
||||
try_clockctl=0
|
||||
feat_scfilter=0
|
||||
try_seccomp=-1
|
||||
try_pledge=0
|
||||
priv_ops=""
|
||||
feat_ipv6=1
|
||||
feat_phc=1
|
||||
@@ -447,6 +448,18 @@ case $OPERATINGSYSTEM in
|
||||
add_def NETBSD
|
||||
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)
|
||||
EXTRA_OBJECTS="sys_macosx.o"
|
||||
LIBS="$LIBS -lresolv"
|
||||
@@ -812,6 +825,12 @@ then
|
||||
EXTRA_OBJECTS="$EXTRA_OBJECTS sys_linux_scmp.o"
|
||||
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
|
||||
EXTRA_OBJECTS="$EXTRA_OBJECTS privops.o"
|
||||
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
|
||||
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
|
||||
adjustment that can be set by the system driver (100000 ppm on Linux, 500 ppm
|
||||
on FreeBSD, NetBSD, and macOS 10.13+, 32500 ppm on illumos).
|
||||
adjustment that can be set by the system driver (100000 ppm on Linux and
|
||||
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
|
||||
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).
|
||||
+
|
||||
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
|
||||
is 5000 ppm, and on illumos it is 32500 ppm. Also, due to a kernel limitation,
|
||||
setting *maxslewrate* on FreeBSD, NetBSD, macOS 10.13+ to a value between 500
|
||||
ppm and 5000 ppm will effectively set it to 500 ppm.
|
||||
by the driver. On Linux and OpenBSD it is 100000 ppm, on FreeBSD, NetBSD and
|
||||
macOS 10.13+ it is 5000 ppm, on illumos it is 32500 ppm. Also, due to a kernel
|
||||
limitation, setting *maxslewrate* on FreeBSD, NetBSD, macOS 10.13+ to a value
|
||||
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).
|
||||
|
||||
@@ -2988,7 +2988,7 @@ file when the <<chronyc.adoc#rekey,*rekey*>> command is issued by *chronyc*).
|
||||
[[lock_all]]*lock_all*::
|
||||
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.
|
||||
The directive is supported on Linux, FreeBSD, NetBSD, and illumos.
|
||||
The directive is supported on Linux, FreeBSD, NetBSD, OpenBSD, and illumos.
|
||||
|
||||
[[pidfile]]*pidfile* _file_::
|
||||
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.
|
||||
|
||||
[[sched_priority]]*sched_priority* _priority_::
|
||||
On Linux, FreeBSD, NetBSD, and illumos, the *sched_priority* directive will
|
||||
select the SCHED_FIFO real-time scheduler at the specified priority (which must
|
||||
be between 0 and 100). On macOS, this option must have either a value of 0 (the
|
||||
default) to disable the thread time constraint policy or 1 for the policy to be
|
||||
enabled.
|
||||
On Linux, FreeBSD, NetBSD, OpenBSD, and illumos, the *sched_priority* directive
|
||||
will select the SCHED_FIFO real-time scheduler at the specified priority (which
|
||||
must be between 0 and 100). On macOS, this option must have either a value of 0
|
||||
(the default) to disable the thread time constraint policy or 1 for the policy
|
||||
to be enabled.
|
||||
+
|
||||
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
|
||||
@@ -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.
|
||||
+
|
||||
On Linux, *chronyd* needs to be compiled with support for the *libcap* library.
|
||||
On macOS, FreeBSD, NetBSD and illumos *chronyd* forks into two processes.
|
||||
The child process retains root privileges, but can only perform a very limited
|
||||
range of privileged system calls on behalf of the parent.
|
||||
On macOS, FreeBSD, NetBSD, OpenBSD, and illumos *chronyd* forks into two
|
||||
processes. The child process retains root privileges, but can only perform a
|
||||
very limited range of privileged system calls on behalf of the parent.
|
||||
+
|
||||
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.
|
||||
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,
|
||||
illumos, and macOS 10.13 or later).
|
||||
OpenBSD, illumos, and macOS 10.13 or later).
|
||||
|
||||
*-R*::
|
||||
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@_.
|
||||
+
|
||||
On Linux, *chronyd* needs to be compiled with support for the *libcap* library.
|
||||
On macOS, FreeBSD, NetBSD, and illumos *chronyd* forks into two processes.
|
||||
The child process retains root privileges, but can only perform a very limited
|
||||
range of privileged system calls on behalf of the parent.
|
||||
On macOS, FreeBSD, NetBSD, OpenBSD, and illumos *chronyd* forks into two
|
||||
processes. The child process retains root privileges, but can only perform a
|
||||
very limited range of privileged system calls on behalf of the parent.
|
||||
|
||||
*-U*::
|
||||
This option disables a check for root privileges to allow *chronyd* to be
|
||||
@@ -159,21 +159,22 @@ specific directives.
|
||||
|
||||
*-F* _level_::
|
||||
This option configures system call filters loaded by *chronyd* processes if it
|
||||
was compiled with support for the Linux secure computing (seccomp) facility.
|
||||
Three levels are defined: 0, 1, 2. The filters are disabled at level 0. At
|
||||
levels 1 and 2, *chronyd* will be killed if it makes a system call which is
|
||||
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.
|
||||
was compiled with support for the Linux secure computing (seccomp) facility or
|
||||
OpenBSD pledge. For Linux three levels are defined: 0, 1, 2, for OpenBSD two
|
||||
levels: 0, 1. The filters are disabled at level 0. On Linux at levels 1 and 2
|
||||
and on OpenBSD at level 1, *chronyd* will be killed if it makes a system call
|
||||
which is blocked by the filters. On Linux 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.
|
||||
+
|
||||
At level 1, the filters allow only selected system calls that are normally
|
||||
expected to be made by *chronyd*. Other system calls are blocked. This level is
|
||||
recommended only if it is known to work on the version of the system where
|
||||
*chrony* is installed. The filters need to allow also system calls made by
|
||||
libraries that *chronyd* is using (e.g. libc), but different versions or
|
||||
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.
|
||||
On Linux at level 1, the filters allow only selected system calls that are
|
||||
normally expected to be made by *chronyd*. Other system calls are blocked.
|
||||
This level is recommended only if it is known to work on the version of the
|
||||
system where *chrony* is installed. The filters need to allow also system
|
||||
calls made by libraries that *chronyd* is using (e.g. libc), but different
|
||||
versions or 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
|
||||
@@ -183,15 +184,15 @@ limited.
|
||||
The filters cannot be enabled with the *mailonchange* directive.
|
||||
|
||||
*-P* _priority_::
|
||||
On Linux, FreeBSD, NetBSD, and illumos this option will select the SCHED_FIFO
|
||||
real-time scheduler at the specified priority (which must be between 0 and
|
||||
100). On macOS, this option must have either a value of 0 to disable the thread
|
||||
time constraint policy or 1 for the policy to be enabled. Other systems do not
|
||||
support this option. The default value is 0.
|
||||
On Linux, FreeBSD, NetBSD, OpenBSD, and illumos this option will select the
|
||||
SCHED_FIFO real-time scheduler at the specified priority (which must be
|
||||
between 0 and 100). On macOS, this option must have either a value of 0 to
|
||||
disable the thread time constraint policy or 1 for the policy to be enabled.
|
||||
Other systems do not support this option. The default value is 0.
|
||||
|
||||
*-m*::
|
||||
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*::
|
||||
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)
|
||||
#include "sys_netbsd.h"
|
||||
#include "sys_posix.h"
|
||||
#elif defined(OPENBSD)
|
||||
#include "sys_openbsd.h"
|
||||
#include "sys_posix.h"
|
||||
#elif defined(MACOSX)
|
||||
#include "sys_macosx.h"
|
||||
#endif
|
||||
@@ -66,6 +69,8 @@ SYS_Initialise(int clock_control)
|
||||
SYS_Solaris_Initialise();
|
||||
#elif defined(NETBSD) || defined(FREEBSD)
|
||||
SYS_NetBSD_Initialise();
|
||||
#elif defined(OPENBSD)
|
||||
SYS_OpenBSD_Initialise();
|
||||
#elif defined(MACOSX)
|
||||
SYS_MacOSX_Initialise();
|
||||
#else
|
||||
@@ -88,6 +93,8 @@ SYS_Finalise(void)
|
||||
SYS_Solaris_Finalise();
|
||||
#elif defined(NETBSD) || defined(FREEBSD)
|
||||
SYS_NetBSD_Finalise();
|
||||
#elif defined(OPENBSD)
|
||||
SYS_OpenBSD_Finalise();
|
||||
#elif defined(MACOSX)
|
||||
SYS_MacOSX_Finalise();
|
||||
#else
|
||||
@@ -105,6 +112,8 @@ void SYS_DropRoot(uid_t uid, gid_t gid, SYS_ProcessContext context)
|
||||
SYS_Solaris_DropRoot(uid, gid, context);
|
||||
#elif (defined(NETBSD) || defined(FREEBSD)) && defined(FEAT_PRIVDROP)
|
||||
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)
|
||||
SYS_MacOSX_DropRoot(uid, gid, context);
|
||||
#else
|
||||
@@ -118,6 +127,8 @@ void SYS_EnableSystemCallFilter(int level, SYS_ProcessContext context)
|
||||
{
|
||||
#if defined(LINUX) && defined(FEAT_SCFILTER)
|
||||
SYS_Linux_EnableSystemCallFilter(level, context);
|
||||
#elif defined(OPENBSD) && defined(FEAT_SCFILTER)
|
||||
SYS_OpenBSD_EnableSystemCallFilter(level, context);
|
||||
#else
|
||||
LOG_FATAL("system call filter not supported");
|
||||
#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"
|
||||
|
||||
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:"
|
||||
for test in 0[0-8][0-9]-*[^_]; do
|
||||
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"
|
||||
|
||||
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:"
|
||||
for test in 1[0-8][0-9]-*[^_]; do
|
||||
test_message 2 0 "$test"
|
||||
|
||||
Reference in New Issue
Block a user