sys_macosx: drop root privileges
Run chronyd as a non-privileged user, using the privops helper to perform adjtime(), settimeofday() and bind() functions on its behalf.
This commit is contained in:
parent
139fc667aa
commit
750d82f1d1
7 changed files with 61 additions and 9 deletions
|
@ -978,7 +978,13 @@ 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
|
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
|
@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
|
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 @code{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 parent process drops
|
||||||
|
root privileges to run as the specified system user.
|
||||||
@item -F <level>
|
@item -F <level>
|
||||||
This option configures a system call filter when @code{chronyd} is compiled with
|
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
|
support for the Linux secure computing (seccomp) facility. In level 1 the
|
||||||
|
@ -3169,8 +3175,13 @@ Valid measurements with corresponding compensations are logged to the
|
||||||
The @code{user} directive sets the name of the system user to which
|
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.
|
@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
|
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
|
support for Linux capabilities (libcap), on NetBSD with the
|
||||||
@code{/dev/clockctl} device.
|
@code{/dev/clockctl} device or on Mac OS X.
|
||||||
|
|
||||||
|
In the Mac OS X implementation @code{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 parent process drops
|
||||||
|
root privileges to run as the specified system user.
|
||||||
|
|
||||||
The default value is @code{@DEFAULT_USER@}.
|
The default value is @code{@DEFAULT_USER@}.
|
||||||
@c }}}
|
@c }}}
|
||||||
|
|
|
@ -103,7 +103,12 @@ 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
|
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
|
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
|
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 \fBchronyd\fR 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 parent process drops
|
||||||
|
root privileges to run as the specified system user.
|
||||||
.TP
|
.TP
|
||||||
\fB\-F\fR \fIlevel\fR
|
\fB\-F\fR \fIlevel\fR
|
||||||
This option configures a system call filter when \fBchronyd\fR is compiled with
|
This option configures a system call filter when \fBchronyd\fR is compiled with
|
||||||
|
|
8
configure
vendored
8
configure
vendored
|
@ -392,6 +392,14 @@ case $OPERATINGSYSTEM in
|
||||||
EXTRA_LIBS="-lresolv"
|
EXTRA_LIBS="-lresolv"
|
||||||
EXTRA_CLI_LIBS="-lresolv"
|
EXTRA_CLI_LIBS="-lresolv"
|
||||||
add_def MACOSX
|
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 ")"
|
echo "Configuring for MacOS X (" $SYSTEM "MacOS X version" $VERSION ")"
|
||||||
;;
|
;;
|
||||||
SunOS)
|
SunOS)
|
||||||
|
|
3
ntp_io.c
3
ntp_io.c
|
@ -37,6 +37,7 @@
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
|
#include "privops.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#define INVALID_SOCK_FD -1
|
#define INVALID_SOCK_FD -1
|
||||||
|
@ -221,7 +222,7 @@ prepare_socket(int family, int port_number, int client_only)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Bind the socket if a port or address was specified */
|
/* 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",
|
LOG(LOGS_ERR, LOGF_NtpIO, "Could not bind %s NTP socket : %s",
|
||||||
UTI_SockaddrFamilyToString(family), strerror(errno));
|
UTI_SockaddrFamilyToString(family), strerror(errno));
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
|
|
2
sys.c
2
sys.c
|
@ -92,6 +92,8 @@ void SYS_DropRoot(uid_t uid, gid_t gid)
|
||||||
SYS_Linux_DropRoot(uid, gid);
|
SYS_Linux_DropRoot(uid, gid);
|
||||||
#elif defined(NETBSD) && defined(FEAT_PRIVDROP)
|
#elif defined(NETBSD) && defined(FEAT_PRIVDROP)
|
||||||
SYS_NetBSD_DropRoot(uid, gid);
|
SYS_NetBSD_DropRoot(uid, gid);
|
||||||
|
#elif defined(MACOSX) && defined(FEAT_PRIVDROP)
|
||||||
|
SYS_MacOSX_DropRoot(uid, gid);
|
||||||
#else
|
#else
|
||||||
LOG_FATAL(LOGF_Sys, "dropping root privileges not supported");
|
LOG_FATAL(LOGF_Sys, "dropping root privileges not supported");
|
||||||
#endif
|
#endif
|
||||||
|
|
32
sys_macosx.c
32
sys_macosx.c
|
@ -50,6 +50,7 @@
|
||||||
#include "localp.h"
|
#include "localp.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
#include "privops.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
@ -117,7 +118,7 @@ clock_initialise(void)
|
||||||
newadj.tv_sec = 0;
|
newadj.tv_sec = 0;
|
||||||
newadj.tv_usec = 0;
|
newadj.tv_usec = 0;
|
||||||
|
|
||||||
if (adjtime(&newadj, &oldadj) < 0) {
|
if (PRV_AdjustTime(&newadj, &oldadj) < 0) {
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
|
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +170,7 @@ start_adjust(void)
|
||||||
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
UTI_TimevalToDouble(&newadj, &adjustment_requested);
|
||||||
rounding_error = adjust_required - 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");
|
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +194,7 @@ stop_adjust(void)
|
||||||
zeroadj.tv_sec = 0;
|
zeroadj.tv_sec = 0;
|
||||||
zeroadj.tv_usec = 0;
|
zeroadj.tv_usec = 0;
|
||||||
|
|
||||||
if (adjtime(&zeroadj, &remadj) < 0) {
|
if (PRV_AdjustTime(&zeroadj, &remadj) < 0) {
|
||||||
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
|
LOG_FATAL(LOGF_SysMacOSX, "adjtime() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +245,7 @@ apply_step_offset(double offset)
|
||||||
|
|
||||||
UTI_AddDoubleToTimeval(&old_time, -offset, &new_time);
|
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");
|
DEBUG_LOG(LOGF_SysMacOSX, "settimeofday() failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -400,6 +401,26 @@ SYS_MacOSX_SetScheduler(int SchedPriority)
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
#ifdef FEAT_PRIVDROP
|
||||||
|
void SYS_MacOSX_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
|
void
|
||||||
SYS_MacOSX_Initialise(void)
|
SYS_MacOSX_Initialise(void)
|
||||||
{
|
{
|
||||||
|
@ -423,6 +444,9 @@ SYS_MacOSX_Finalise(void)
|
||||||
SCH_RemoveTimeout(drift_removal_id);
|
SCH_RemoveTimeout(drift_removal_id);
|
||||||
|
|
||||||
clock_finalise();
|
clock_finalise();
|
||||||
|
#ifdef FEAT_PRIVDROP
|
||||||
|
PRV_Finalise();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#define GOT_SYS_MACOSX_H
|
#define GOT_SYS_MACOSX_H
|
||||||
|
|
||||||
void SYS_MacOSX_SetScheduler(int SchedPriority);
|
void SYS_MacOSX_SetScheduler(int SchedPriority);
|
||||||
|
void SYS_MacOSX_DropRoot(uid_t uid, gid_t gid);
|
||||||
void SYS_MacOSX_Initialise(void);
|
void SYS_MacOSX_Initialise(void);
|
||||||
void SYS_MacOSX_Finalise(void);
|
void SYS_MacOSX_Finalise(void);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue