[chrony-dev] MacOS X - separation of privileges

[ Thread Index | Date Index | More chrony.tuxfamily.org/chrony-dev Archives ]


Hi Miroslav

I've been doing some work on privilege separation and finally have it working, using a small helper program to perform the privileged system calls - see below for some details on what I've done and how it works

My question - how to neatly incorporate this into the chrony source tree. The helper program is be MacOS only so should only be built if the target system is MacOS. It also requires codesigning and the person compiling the software must
provide their own certificate. chronyd also has to be signed for the mechanism to work.

My current implementation has all the helper code outside the chrony source tree

I'm thinking of adding a directory (macoshelper) to the source tree, with its own Makefile but wanted to check with you before I go there.

This is really a prototype - it simply places adjtime() and setttimeofday() in the privileged helper and the results are actually surprisingly good. It would be possible to move more of the driver code into the privileged tool and cut down on the IPC overhead, but thats a lot more work and I think shouldn't be attempted until the build method is finalised.

Sorry to be so long winded.
Bryan

===================================================================================

Separation of privileges on MacOS X
-----------------------------------

Bryan Christianson - October, 2015

The recommended method (by Apple) for separating privileges on MacOS X
is to run a small helper program with root privilege to perform actions
on behalf of a more complex daemon.

After chronyd is initialised (as root) the only privileged system calls
required are adjtime() and settimeofday(). These can easily be handled
with a simple IPC method.

chronyd achieves this by

1. Start chronyd from launchd at system startup as uid root

2. chronyd uses launchd to start a helper program (org.tuxfamily.chronydhelper)
and connects to it via a unix socket

3. chronyd drops uid root and switches (via the setuid() call) to uid daemon

4. chronyd sends and receives messages over the unix socket to perform privileged
operations

CONS
The use of a unix socket will introduce latency and jitter into the system
calls and will cause chronyd to be less precise than if it were to run as a
root process performing its own system calls. Experiments show that the
error introduced is small (< 10 usecs)

PROS
Privilege separation is a further guard against malicious attacks from the
Internet. chronyd (potentially) exposes ports to the Internet and if these
ports are successfully compromised by an attacker, the machine is easily
taken over.

SECURITY
The launchd mechanism provides security features to prevent unauthorised
software from either launching or connecting (via the unix socket) to the
helper program.

The MacOS X linker adds authorisation structures to both the helper program
and chronyd via the -sectcreate option

e.g. The helper program is linked with the following options
-sectcreate __TEXT __info_plist Resources/info.plist \
-sectcreate __TEXT __launchd_plist Resources/org.tuxfamily.chronydhelper.plist

The .plist files linked to the helper specify the program's launchd registration data
along with the identity of all client software, including details of their code
signing certificates. They also specify the IPC method (in this case a unix socket)
and the relevant address/path names and socket permissions

In this implementation, the unix socket is be owned by root and is only
allowed to be opened by root

CODESIGNING
Both chronyd and org.tuxfamily.chronydhelper must be signed using an appropriate
codesigning certificate. If either program is tampered with, the operating system
will refuse to run it. If the software is unsigned, launchd will not run it.

The same certificate should be used for signing both programs.

LAUNCHING THE HELPER
The helper program is registered with launchd when it is installed on the system.
launchd then is able to associate the unix socket path specified in the authorisation
information with the helper executable. When chronyd attempts to open the socket
(as root) launchd will verify the authorisation mutually held between chronyd and
the helper, then launch the helper. When chronyd closes the socket, the helper will exit.

After opening the socket, chronyd now has an authorised connection to the helper
and can drop root privileges, this achieving separation of privilege.


--
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.


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/