[chrony-dev] [PATCH] MacOS X - Drop root privilege |
[ Thread Index |
Date Index
| More chrony.tuxfamily.org/chrony-dev Archives
]
- To: chrony-dev@xxxxxxxxxxxxxxxxxxxx
- Subject: [chrony-dev] [PATCH] MacOS X - Drop root privilege
- From: Bryan Christianson <bryan@xxxxxxxxxxxxx>
- Date: Tue, 24 Nov 2015 21:01:59 +1300
- Cc: Bryan Christianson <bryan@xxxxxxxxxxxxx>
- Dkim-signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpcorp.com; s=a0-2; h=Feedback-ID:X-Smtpcorp-Track:Message-Id:Date: Subject:To:From; bh=tGxc0WPDg4a+k8Hvug174ftN0myF06JVR4CGw2isn4Y=; b=ZzR30GgPz WJwfoUzs0lNvtwyNDQxHIfBCydyLUzF2RSLis6p2aN+HoB7X4RCdvU6CuNJoxQh0kmFS9d8IRN/sc mNOUaduslI5x689sfsLL1mk/Eqw4dPkWZTar9GRGd41v91isJ9gHmAmh2NzJYTLMGjBd64ezAhKQw 5xJt/yJpZW/HOdhCwNGx/hc3J6DuB251VgYY32FzYPuGBhA5xSSU7AnzTRHcFeL1JAi1LUqSOIDUP HOdn44sxLce/15gUD/Ab+nQwrLiZL/hQl3kEl6CPqrc5MiUOwzpgLdeuHlUiUkCQqaqxkzoPxJCLe p78s2NlnBIMCbXU3GjKyt4iVQ==;
- Feedback-id: 149811m:149811acx33YQ:149811sLEXyL30He:SMTPCORP
Run chronyd as a non-privileged user, using the privops helper to
perform adjtime(), settimeofday() and bind() functions on its behalf.
---
chrony.texi.in | 13 ++++++++++---
chronyd.8.in | 8 +++++++-
configure | 8 ++++++++
ntp_io.c | 3 ++-
sys.c | 2 ++
sys_macosx.c | 32 ++++++++++++++++++++++++++++----
sys_macosx.h | 1 +
7 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/chrony.texi.in b/chrony.texi.in
index 18ebfce..06f24ff 100644
--- a/chrony.texi.in
+++ b/chrony.texi.in
@@ -978,7 +978,14 @@ This option sets the name of the system user to which @code{chronyd} will
switch after start in order to drop root privileges. It overrides the
@code{user} directive (default @code{@DEFAULT_USER@}). It may be set to a
non-root user only when @code{chronyd} is compiled with support for Linux
-capabilities (libcap) or on NetBSD with the @code{/dev/clockctl} device.
+capabilities (libcap), on NetBSD with the @code{/dev/clockctl} device or on
+Mac OS X.
+
+In the Mac OS X implementation chronyd forks into two processes. The
+child process retains root privilege but can only perform a very limited range
+of privileged system calls on behalf of the parent. The parent process drops
+root privilege to run as the specified system user. Both processes are visible
+in the list of running processes.
@item -F <level>
This option configures a system call filter when @code{chronyd} is compiled with
support for the Linux secure computing (seccomp) facility. In level 1 the
@@ -3169,8 +3176,8 @@ Valid measurements with corresponding compensations are logged to the
The @code{user} directive sets the name of the system user to which
@code{chronyd} will switch after start in order to drop root privileges.
It may be set to a non-root user only when @code{chronyd} is compiled with
-support for Linux capabilities (libcap) or on NetBSD with the
-@code{/dev/clockctl} device.
+support for Linux capabilities (libcap), on NetBSD with the
+@code{/dev/clockctl} device or on MaxOS X.
The default value is @code{@DEFAULT_USER@}.
@c }}}
diff --git a/chronyd.8.in b/chronyd.8.in
index b5b0882..a2889d2 100644
--- a/chronyd.8.in
+++ b/chronyd.8.in
@@ -103,7 +103,13 @@ This option sets the name of the system user to which \fBchronyd\fR will switch
after start in order to drop root privileges. It overrides the \fBuser\fR
directive (default \fB@DEFAULT_USER@\fR). It may be set to a non-root user
only when \fBchronyd\fR is compiled with support for Linux capabilities
-(libcap) or on NetBSD with the \fB/dev/clockctl\fR device.
+(libcap), on NetBSD with the \fB/dev/clockctl\fR device or on Mac OS X.
+
+In the Mac OS X implementation chronyd forks into two processes. The child
+process retains root privilege but can only perform a very limited range of
+privileged system calls on behalf of the parent. The parent process drops
+root privilege to run as the specified system user. Both processes are visible
+in the list of running processes.
.TP
\fB\-F\fR \fIlevel\fR
This option configures a system call filter when \fBchronyd\fR is compiled with
diff --git a/configure b/configure
index 16fdf8d..5a52abf 100755
--- a/configure
+++ b/configure
@@ -392,6 +392,14 @@ case $OPERATINGSYSTEM in
EXTRA_LIBS="-lresolv"
EXTRA_CLI_LIBS="-lresolv"
add_def MACOSX
+ if [ $feat_droproot = "1" ]; then
+ EXTRA_OBJECTS="$EXTRA_OBJECTS privops.o"
+ add_def PRIVOPS_ADJUSTTIME
+ add_def PRIVOPS_SETTIME
+ add_def PRIVOPS_BINDSOCKET
+ add_def PRIVOPS_HELPER
+ add_def FEAT_PRIVDROP
+ fi
echo "Configuring for MacOS X (" $SYSTEM "MacOS X version" $VERSION ")"
;;
SunOS)
diff --git a/ntp_io.c b/ntp_io.c
index 24b1190..4c250ae 100644
--- a/ntp_io.c
+++ b/ntp_io.c
@@ -37,6 +37,7 @@
#include "local.h"
#include "logging.h"
#include "conf.h"
+#include "privops.h"
#include "util.h"
#define INVALID_SOCK_FD -1
@@ -221,7 +222,7 @@ prepare_socket(int family, int port_number, int client_only)
#endif
/* Bind the socket if a port or address was specified */
- if (my_addr_len > 0 && bind(sock_fd, &my_addr.u, my_addr_len) < 0) {
+ if (my_addr_len > 0 && PRV_BindSocket(sock_fd, &my_addr.u, my_addr_len) < 0) {
LOG(LOGS_ERR, LOGF_NtpIO, "Could not bind %s NTP socket : %s",
UTI_SockaddrFamilyToString(family), strerror(errno));
close(sock_fd);
diff --git a/sys.c b/sys.c
index 4009796..613ef74 100644
--- a/sys.c
+++ b/sys.c
@@ -92,6 +92,8 @@ void SYS_DropRoot(uid_t uid, gid_t gid)
SYS_Linux_DropRoot(uid, gid);
#elif defined(NETBSD) && defined(FEAT_PRIVDROP)
SYS_NetBSD_DropRoot(uid, gid);
+#elif defined(MACOSX) && defined(FEAT_PRIVDROP)
+ SYS_MaxOSX_DropRoot(uid, gid);
#else
LOG_FATAL(LOGF_Sys, "dropping root privileges not supported");
#endif
diff --git a/sys_macosx.c b/sys_macosx.c
index d1b620f..fc52702 100644
--- a/sys_macosx.c
+++ b/sys_macosx.c
@@ -50,6 +50,7 @@
#include "localp.h"
#include "sched.h"
#include "logging.h"
+#include "privops.h"
#include "util.h"
/* ================================================== */
@@ -117,7 +118,7 @@ clock_initialise(void)
newadj.tv_sec = 0;
newadj.tv_usec = 0;
- if (adjtime(&newadj, &oldadj) < 0) {
+ if (PRV_AdjustTime(&newadj, &oldadj) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
}
}
@@ -169,7 +170,7 @@ start_adjust(void)
UTI_TimevalToDouble(&newadj, &adjustment_requested);
rounding_error = adjust_required - adjustment_requested;
- if (adjtime(&newadj, &oldadj) < 0) {
+ if (PRV_AdjustTime(&newadj, &oldadj) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
}
@@ -193,7 +194,7 @@ stop_adjust(void)
zeroadj.tv_sec = 0;
zeroadj.tv_usec = 0;
- if (adjtime(&zeroadj, &remadj) < 0) {
+ if (PRV_AdjustTime(&zeroadj, &remadj) < 0) {
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
}
@@ -244,7 +245,7 @@ apply_step_offset(double offset)
UTI_AddDoubleToTimeval(&old_time, -offset, &new_time);
- if (settimeofday(&new_time, NULL) < 0) {
+ if (PRV_SetTime(&new_time, NULL) < 0) {
DEBUG_LOG(LOGF_SysMacOSX, "settimeofday() failed");
return 0;
}
@@ -400,6 +401,26 @@ SYS_MacOSX_SetScheduler(int SchedPriority)
/* ================================================== */
+#ifdef FEAT_PRIVDROP
+void SYS_MaxOSX_DropRoot(uid_t uid, gid_t gid)
+{
+ PRV_Initialise();
+
+ if (setgroups(0, NULL))
+ LOG_FATAL(LOGF_SysMacOSX, "setgroups() failed : %s", strerror(errno));
+
+ if (setgid(gid))
+ LOG_FATAL(LOGF_SysMacOSX, "setgid(%d) failed : %s", gid, strerror(errno));
+
+ if (setuid(uid))
+ LOG_FATAL(LOGF_SysMacOSX, "setuid(%d) failed : %s", uid, strerror(errno));
+
+ DEBUG_LOG(LOGF_SysMacOSX, "Root dropped to uid %d gid %d", uid, gid);
+}
+#endif
+
+/* ================================================== */
+
void
SYS_MacOSX_Initialise(void)
{
@@ -423,6 +444,9 @@ SYS_MacOSX_Finalise(void)
SCH_RemoveTimeout(drift_removal_id);
clock_finalise();
+#ifdef FEAT_PRIVDROP
+ PRV_Finalise();
+#endif
}
/* ================================================== */
diff --git a/sys_macosx.h b/sys_macosx.h
index 707700d..b9ae905 100644
--- a/sys_macosx.h
+++ b/sys_macosx.h
@@ -31,6 +31,7 @@
#define GOT_SYS_MACOSX_H
void SYS_MacOSX_SetScheduler(int SchedPriority);
+void SYS_MaxOSX_DropRoot(uid_t uid, gid_t gid);
void SYS_MacOSX_Initialise(void);
void SYS_MacOSX_Finalise(void);
--
2.4.9 (Apple Git-60)
--
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.