From 54c8732c460c585ae3ad59f52317168c6fa193c2 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 12 Jan 2016 17:52:34 +0100 Subject: [PATCH] sys_linux: use privops helper when running with seccomp filter Enable the PRV_Name2IPAddress() function with seccomp support and start the helper process before loading the seccomp filter (but after dropping root privileges). This will move the getaddrinfo() call outside the seccomp filter and should make it more reliable as the list of required system calls won't depend on what glibc NSS modules are used on the system. --- chrony.texi.in | 7 +++++++ chronyd.8.in | 7 +++++++ configure | 4 ++++ doc/faq.adoc | 13 +++++++------ sys_linux.c | 9 ++++++++- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/chrony.texi.in b/chrony.texi.in index dc8f817..4f643db 100644 --- a/chrony.texi.in +++ b/chrony.texi.in @@ -988,6 +988,13 @@ 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 process is killed when a forbidden system call is made, in level -1 the SYSSIG signal is thrown instead and in level 0 the filter is disabled (default 0). + +It's recommended to enable the filter only when it's known to work on the +version of the system where @code{chrony} is installed as the filter needs to +allow also system calls made from libraries that @code{chronyd} is using (e.g. +libc) and different versions or implementations of the libraries may make +different system calls. If the filter is missing some system call, +@code{chronyd} could be killed even in normal operation. @item -q When run in this mode, @code{chronyd} will set the system clock once and exit. It will not detach from the terminal. diff --git a/chronyd.8.in b/chronyd.8.in index bd27ba0..0cd06a5 100644 --- a/chronyd.8.in +++ b/chronyd.8.in @@ -113,6 +113,13 @@ This option configures a system call filter when \fBchronyd\fR is compiled with support for the Linux secure computing (seccomp) facility. In level 1 the process is killed when a forbidden system call is made, in level -1 the SYSSIG signal is thrown instead and in level 0 the filter is disabled (default 0). + +It's recommended to enable the filter only when it's known to work on the +version of the system where \fBchrony\fR is installed as the filter needs to +allow also system calls made from libraries that \fBchronyd\fR is using (e.g. +libc) and different versions or implementations of the libraries may make +different system calls. If the filter is missing some system call, +\fBchronyd\fR could be killed even in normal operation. .TP .B \-q When run in this mode, chronyd will set the system clock once diff --git a/configure b/configure index 9869f55..8608c8d 100755 --- a/configure +++ b/configure @@ -629,6 +629,10 @@ if [ $feat_scfilter = "1" ] && [ $try_seccomp = "1" ] && \ 'seccomp_init(SCMP_ACT_KILL);' then add_def FEAT_SCFILTER + # NAME2IPADDRESS shouldn't be enabled with other operations as the helper + # process works on one request at the time and the async resolver could + # block the main thread + priv_ops="NAME2IPADDRESS" EXTRA_LIBS="$EXTRA_LIBS -lseccomp" fi diff --git a/doc/faq.adoc b/doc/faq.adoc index 5869a65..003b953 100644 --- a/doc/faq.adoc +++ b/doc/faq.adoc @@ -139,12 +139,13 @@ a very limited range of privileged system calls on behalf of the parent. Also, if +chronyd+ is compiled with support for the Linux secure computing (seccomp) facility, you can enable a system call filter with the +-F+ option. It will significantly reduce the kernel attack surface and possibly prevent -kernel exploits from the +chronyd+ process if compromised. The filter -shouldn't be enabled without testing that it allows all system calls needed -with the specific configuration and libraries that +chronyd+ is using (e.g. -libc and its NSS configuration). If +chronyd+ is getting killed, some system -call is missing and the filter has to be disabled until it's patched to allow -that call. +kernel exploits from the +chronyd+ process if it's compromised. It's +recommended to enable the filter only when it's known to work on the version of +the system where +chrony+ is installed as the filter needs to allow also system +calls made from libraries that +chronyd+ is using (e.g. libc) and different +versions or implementations of the libraries may make different system calls. +If the filter is missing some system call, +chronyd+ could be killed even in +normal operation. === How can I improve the accuracy of the system clock with NTP sources? diff --git a/sys_linux.c b/sys_linux.c index 8ef6de0..8004771 100644 --- a/sys_linux.c +++ b/sys_linux.c @@ -65,6 +65,7 @@ #include "sys_timex.h" #include "conf.h" #include "logging.h" +#include "privops.h" #include "util.h" /* Frequency scale to convert from ppm to the timex freq */ @@ -455,7 +456,7 @@ SYS_Linux_EnableSystemCallFilter(int level) /* Process */ SCMP_SYS(clone), SCMP_SYS(exit), SCMP_SYS(exit_group), SCMP_SYS(getrlimit), SCMP_SYS(rt_sigaction), SCMP_SYS(rt_sigreturn), SCMP_SYS(rt_sigprocmask), - SCMP_SYS(set_tid_address), SCMP_SYS(sigreturn), + SCMP_SYS(set_tid_address), SCMP_SYS(sigreturn), SCMP_SYS(wait4), /* Memory */ SCMP_SYS(brk), SCMP_SYS(madvise), SCMP_SYS(mmap), SCMP_SYS(mmap2), SCMP_SYS(mprotect), SCMP_SYS(mremap), SCMP_SYS(munmap), SCMP_SYS(shmdt), @@ -515,6 +516,12 @@ SYS_Linux_EnableSystemCallFilter(int level) /* Check if the chronyd configuration is supported */ check_seccomp_applicability(); + /* Start the helper process, which will run without any seccomp filter. It + will be used for getaddrinfo(), for which it's difficult to maintain a + list of required system calls (with glibc it depends on what NSS modules + are installed and enabled on the system). */ + PRV_StartHelper(); + ctx = seccomp_init(level > 0 ? SCMP_ACT_KILL : SCMP_ACT_TRAP); if (ctx == NULL) LOG_FATAL(LOGF_SysLinux, "Failed to initialize seccomp");