sys_linux: add syscall filter context for NTS-KE

The NTS-KE helper process will use a more restrictive filter than the
main process.
This commit is contained in:
Miroslav Lichvar 2019-11-26 14:16:47 +01:00
parent e6848b1e3f
commit 1d4690eb64
2 changed files with 40 additions and 35 deletions

1
sys.h
View file

@ -40,6 +40,7 @@ extern void SYS_DropRoot(uid_t uid, gid_t gid);
typedef enum { typedef enum {
SYS_MAIN_PROCESS, SYS_MAIN_PROCESS,
SYS_NTSKE_HELPER,
} SYS_SystemCallContext; } SYS_SystemCallContext;
/* Enable a system call filter to allow only system calls /* Enable a system call filter to allow only system calls

View file

@ -559,14 +559,16 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_SystemCallContext context)
scmp_filter_ctx *ctx; scmp_filter_ctx *ctx;
int i; int i;
/* Check if the chronyd configuration is supported */ if (context == SYS_MAIN_PROCESS) {
check_seccomp_applicability(); /* Check if the chronyd configuration is supported */
check_seccomp_applicability();
/* Start the helper process, which will run without any seccomp filter. It /* 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 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 list of required system calls (with glibc it depends on what NSS modules
are installed and enabled on the system). */ are installed and enabled on the system). */
PRV_StartHelper(); PRV_StartHelper();
}
ctx = seccomp_init(level > 0 ? SCMP_ACT_KILL : SCMP_ACT_TRAP); ctx = seccomp_init(level > 0 ? SCMP_ACT_KILL : SCMP_ACT_TRAP);
if (ctx == NULL) if (ctx == NULL)
@ -578,42 +580,44 @@ SYS_Linux_EnableSystemCallFilter(int level, SYS_SystemCallContext context)
goto add_failed; goto add_failed;
} }
/* Allow sockets to be created only in selected domains */ if (context == SYS_MAIN_PROCESS) {
for (i = 0; i < sizeof (socket_domains) / sizeof (*socket_domains); i++) { /* Allow opening sockets in selected domains */
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1, for (i = 0; i < sizeof (socket_domains) / sizeof (*socket_domains); i++) {
SCMP_A0(SCMP_CMP_EQ, socket_domains[i])) < 0) if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 1,
goto add_failed; SCMP_A0(SCMP_CMP_EQ, socket_domains[i])) < 0)
} goto add_failed;
}
/* Allow setting only selected sockets options */ /* Allow selected socket options */
for (i = 0; i < sizeof (socket_options) / sizeof (*socket_options); i++) { for (i = 0; i < sizeof (socket_options) / sizeof (*socket_options); i++) {
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 3, if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 3,
SCMP_A1(SCMP_CMP_EQ, socket_options[i][0]), SCMP_A1(SCMP_CMP_EQ, socket_options[i][0]),
SCMP_A2(SCMP_CMP_EQ, socket_options[i][1]), SCMP_A2(SCMP_CMP_EQ, socket_options[i][1]),
SCMP_A4(SCMP_CMP_LE, sizeof (int))) < 0) SCMP_A4(SCMP_CMP_LE, sizeof (int))) < 0)
goto add_failed; goto add_failed;
} }
/* Allow only selected fcntl calls */ /* Allow selected fcntl calls */
for (i = 0; i < sizeof (fcntls) / sizeof (*fcntls); i++) { for (i = 0; i < sizeof (fcntls) / sizeof (*fcntls); i++) {
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl), 1, if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl), 1,
SCMP_A1(SCMP_CMP_EQ, fcntls[i])) < 0 || SCMP_A1(SCMP_CMP_EQ, fcntls[i])) < 0 ||
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1, seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1,
SCMP_A1(SCMP_CMP_EQ, fcntls[i])) < 0) SCMP_A1(SCMP_CMP_EQ, fcntls[i])) < 0)
goto add_failed; goto add_failed;
} }
/* Allow only selected ioctls */ /* Allow selected ioctls */
for (i = 0; i < sizeof (ioctls) / sizeof (*ioctls); i++) { for (i = 0; i < sizeof (ioctls) / sizeof (*ioctls); i++) {
if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1, if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1,
SCMP_A1(SCMP_CMP_EQ, ioctls[i])) < 0) SCMP_A1(SCMP_CMP_EQ, ioctls[i])) < 0)
goto add_failed; goto add_failed;
}
} }
if (seccomp_load(ctx) < 0) if (seccomp_load(ctx) < 0)
LOG_FATAL("Failed to load seccomp rules"); LOG_FATAL("Failed to load seccomp rules");
LOG(LOGS_INFO, "Loaded seccomp filter"); LOG(context == SYS_MAIN_PROCESS ? LOGS_INFO : LOGS_DEBUG, "Loaded seccomp filter");
seccomp_release(ctx); seccomp_release(ctx);
return; return;