[chrony-dev] [PATCH] Add support for OpenBSD |
[ Thread Index |
Date Index
| More chrony.tuxfamily.org/chrony-dev Archives
]
---
configure | 12 +++++
privops.c | 71 +++++++++++++++++++++++++
privops.h | 6 +++
sys.c | 9 ++++
sys_openbsd.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++
sys_openbsd.h | 39 ++++++++++++++
sysincl.h | 4 ++
7 files changed, 283 insertions(+)
create mode 100644 sys_openbsd.c
create mode 100644 sys_openbsd.h
diff --git a/configure b/configure
index 8041d4e..fe40b61 100755
--- a/configure
+++ b/configure
@@ -446,6 +446,18 @@ case $OPERATINGSYSTEM in
add_def NETBSD
echo "Configuring for $SYSTEM"
;;
+ OpenBSD)
+ try_recvmmsg=0
+ EXTRA_OBJECTS="sys_generic.o sys_openbsd.o sys_posix.o"
+ try_setched=1
+ try_lockmem=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"
diff --git a/privops.c b/privops.c
index 3fb5cbd..64aa7d7 100644
--- a/privops.c
+++ b/privops.c
@@ -42,6 +42,7 @@
#define OP_BINDSOCKET 1027
#define OP_NAME2IPADDRESS 1028
#define OP_RELOADDNS 1029
+#define OP_ADJUSTFREQ 1030
#define OP_QUIT 1099
union sockaddr_in46 {
@@ -78,6 +79,12 @@ typedef struct {
char name[256];
} ReqName2IPAddress;
+#ifdef PRIVOPS_ADJUSTFREQ
+typedef struct {
+ int64_t freq;
+} ReqAdjustFreq;
+#endif
+
typedef struct {
int op;
union {
@@ -89,6 +96,9 @@ typedef struct {
ReqBindSocket bind_socket;
#ifdef PRIVOPS_NAME2IPADDRESS
ReqName2IPAddress name_to_ipaddress;
+#endif
+#ifdef PRIVOPS_ADJUSTFREQ
+ ReqAdjustFreq adjust_freq;
#endif
} data;
} PrvRequest;
@@ -109,6 +119,10 @@ typedef struct {
IPAddr addresses[DNS_MAX_ADDRESSES];
} ResName2IPAddress;
+typedef struct {
+ int64_t oldfreq;
+} ResAdjustFreq;
+
typedef struct {
char msg[256];
} ResFatalMsg;
@@ -125,6 +139,9 @@ typedef struct {
#endif
#ifdef PRIVOPS_NAME2IPADDRESS
ResName2IPAddress name_to_ipaddress;
+#endif
+#ifdef PRIVOPS_ADJUSTFREQ
+ ResAdjustFreq adjust_freq;
#endif
} data;
} PrvResponse;
@@ -299,6 +316,21 @@ do_reload_dns(PrvResponse *res)
}
#endif
+
+/* ======================================================================= */
+
+/* HELPER - perform adjustfreq() */
+
+#ifdef PRIVOPS_ADJUSTFREQ
+static void
+do_adjust_freq(const ReqAdjustFreq *req, PrvResponse *res)
+{
+ res->rc = adjfreq(&req->freq, &res->data.adjust_freq.oldfreq);
+ if (res->rc)
+ res->res_errno = errno;
+}
+#endif
+
/* ======================================================================= */
/* HELPER - main loop - action requests from the daemon */
@@ -347,6 +379,11 @@ helper_main(int fd)
case OP_RELOADDNS:
do_reload_dns(&res);
break;
+#endif
+#ifdef PRIVOPS_ADJUSTFREQ
+ case OP_ADJUSTFREQ:
+ do_adjust_freq(&req.data.adjust_freq, &res);
+ break;
#endif
case OP_QUIT:
quit = 1;
@@ -623,6 +660,34 @@ PRV_ReloadDNS(void)
/* ======================================================================= */
+/* DAEMON - request adjfreq() */
+
+#ifdef PRIVOPS_ADJUSTFREQ
+int
+PRV_AdjustFreq(const int64_t *freq, int64_t *oldfreq)
+{
+ PrvRequest req;
+ PrvResponse res;
+
+ if (!have_helper() || freq == NULL)
+ /* helper is not running or read adjustment call */
+ return adjfreq(freq, oldfreq);
+
+ memset(&req, 0, sizeof (req));
+ req.op = OP_ADJUSTFREQ;
+ req.data.adjust_freq.freq = *freq;
+
+ submit_request(&req, &res);
+
+ if (oldfreq)
+ *oldfreq = res.data.adjust_freq.oldfreq;
+
+ return res.rc;
+}
+#endif
+
+/* ======================================================================= */
+
void
PRV_Initialise(void)
{
@@ -667,6 +732,12 @@ PRV_StartHelper(void)
/* ignore signals, the process will exit on OP_QUIT request */
UTI_SetQuitSignalsHandler(SIG_IGN, 1);
+
+#ifdef OPENBSD
+ if (pledge("stdio unix settime", NULL) == -1)
+ LOG_FATAL("pledge() failed");
+#endif
+
helper_main(sock_fd2);
} else {
diff --git a/privops.h b/privops.h
index 146580b..fdd0844 100644
--- a/privops.h
+++ b/privops.h
@@ -64,6 +64,12 @@ void PRV_ReloadDNS(void);
#define PRV_ReloadDNS DNS_Reload
#endif
+#ifdef PRIVOPS_ADJUSTFREQ
+int PRV_AdjustFreq(const int64_t *freq, int64_t *oldfreq);
+#else
+#define PRV_AdjustFreq adjfreq
+#endif
+
#ifdef PRIVOPS_HELPER
void PRV_Initialise(void);
void PRV_StartHelper(void);
diff --git a/sys.c b/sys.c
index 1a1a432..6f597af 100644
--- a/sys.c
+++ b/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
diff --git a/sys_openbsd.c b/sys_openbsd.c
new file mode 100644
index 0000000..1c8f781
--- /dev/null
+++ b/sys_openbsd.c
@@ -0,0 +1,142 @@
+/*
+ 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
+ *
+ * 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_generic.h"
+#include "sys_openbsd.h"
+#include "logging.h"
+#include "privops.h"
+#include "util.h"
+
+/* Maximum frequency offset accepted by the kernel (in ppm) */
+#define MAX_FREQ 500000.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 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) == -1)
+ 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");
+}
+
+
+/* ================================================== */
+
+void
+SYS_OpenBSD_Initialise(void)
+{
+ struct clockinfo cinfo;
+
+ cinfo = get_clockinfo();
+ reset_adjtime_offset();
+
+ SYS_Generic_CompleteFreqDriver(MAX_FREQ, 1.0 / cinfo.hz,
+ read_frequency, set_frequency, NULL,
+ 0.0, 0.0,
+ NULL, NULL,
+ NULL, NULL);
+}
+
+/* ================================================== */
+
+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);
+
+ if (pledge("stdio rpath wpath cpath unix inet dns settime", NULL) == -1)
+ LOG_FATAL("pledge() failed");
+}
+#endif
diff --git a/sys_openbsd.h b/sys_openbsd.h
new file mode 100644
index 0000000..d4cf7ef
--- /dev/null
+++ b/sys_openbsd.h
@@ -0,0 +1,39 @@
+/*
+ chronyd/chronyc - Programs for keeping computer clocks accurate.
+
+ **********************************************************************
+ * Copyright (C) Richard P. Curnow 1997-2001
+ * Copyright (C) J. Hannken-Illjes 2001
+ *
+ * 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);
+
+#endif
diff --git a/sysincl.h b/sysincl.h
index e26b236..3494481 100644
--- a/sysincl.h
+++ b/sysincl.h
@@ -62,6 +62,10 @@
#include <sys/timex.h>
#endif
+#if defined(OPENBSD)
+#include <sys/sysctl.h>
+#endif
+
#ifdef HAVE_GETRANDOM
#include <sys/random.h>
#endif
--
2.34.0
--
To unsubscribe email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "unsubscribe" in the subject.
For help email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "help" in the subject.
Trouble? Email listmaster@xxxxxxxxxxxxxxxxxxxx.