seccomp: check more error codes from seccomp_load()

We noticed in our tests that occasionally SystemCallFilter= would
fail to set and the service would run with no syscall filtering.
Most of the time the same tests would apply the filter and fail
the service as expected. While it's not totally clear why this happens,
we noticed seccomp_load() in the systemd code base would fail open for
all errors except EPERM and EACCES.

ENOMEM, EINVAL, and EFAULT seem like reasonable values to add to the
error set based on what I gather from libseccomp code and man pages:

-ENOMEM: out of memory, failed to allocate space for a libseccomp structure, or would exceed a defined constant
-EINVAL: kernel isn't configured to support the operations, args are invalid (to seccomp_load(), seccomp(), or prctl())
-EFAULT: addresses passed as args are invalid
This commit is contained in:
Anita Zhang 2019-04-10 16:08:41 -07:00 committed by Lennart Poettering
parent 03abeb0baf
commit 7bc5e0b12b
4 changed files with 20 additions and 14 deletions

View File

@ -187,7 +187,7 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **sys
return r;
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return log_error_errno(r, "Failed to install seccomp filter: %m");
if (r < 0)
log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -223,7 +223,7 @@ int setup_seccomp(uint64_t cap_list_retain, char **syscall_whitelist, char **sys
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return log_error_errno(r, "Failed to install seccomp audit filter: %m");
if (r < 0)
log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));

View File

@ -2948,7 +2948,7 @@ static int inner_child(
if (is_seccomp_available()) {
r = seccomp_load(arg_seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return log_error_errno(r, "Failed to install seccomp filter: %m");
if (r < 0)
log_debug_errno(r, "Failed to install seccomp filter: %m");

View File

@ -952,7 +952,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
return log_debug_errno(r, "Failed to add filter set: %m");
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1007,7 +1007,7 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* set, u
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1193,7 +1193,7 @@ int seccomp_restrict_namespaces(unsigned long retain) {
continue;
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to install namespace restriction rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1230,7 +1230,7 @@ int seccomp_protect_sysctl(void) {
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to install sysctl protection rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1394,7 +1394,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) {
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to install socket family rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1471,7 +1471,7 @@ int seccomp_restrict_realtime(void) {
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to install realtime protection rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1598,7 +1598,7 @@ int seccomp_memory_deny_write_execute(void) {
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to install MemoryDenyWriteExecute= rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1651,7 +1651,7 @@ int seccomp_restrict_archs(Set *archs) {
return r;
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to restrict system call architectures, skipping: %m");
@ -1753,7 +1753,7 @@ int seccomp_lock_personality(unsigned long personality) {
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to enable personality lock for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1794,7 +1794,7 @@ int seccomp_protect_hostname(void) {
}
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to apply hostname restrictions for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
@ -1956,7 +1956,7 @@ int seccomp_restrict_suid_sgid(void) {
continue;
r = seccomp_load(seccomp);
if (IN_SET(r, -EPERM, -EACCES))
if (ERRNO_IS_SECCOMP_FATAL(r))
return r;
if (r < 0)
log_debug_errno(r, "Failed to apply suid/sgid restrictions for architecture %s, skipping: %m", seccomp_arch_to_string(arch));

View File

@ -95,6 +95,12 @@ extern const uint32_t seccomp_local_archs[];
seccomp_local_archs[_i] != (uint32_t) -1; \
(arch) = seccomp_local_archs[++_i])
/* EACCES: does not have the CAP_SYS_ADMIN or no_new_privs == 1
* ENOMEM: out of memory, failed to allocate space for a libseccomp structure, or would exceed a defined constant
* EFAULT: addresses passed as args (by libseccomp) are invalid */
#define ERRNO_IS_SECCOMP_FATAL(r) \
IN_SET(abs(r), EPERM, EACCES, ENOMEM, EFAULT)
DEFINE_TRIVIAL_CLEANUP_FUNC(scmp_filter_ctx, seccomp_release);
int parse_syscall_archs(char **l, Set **archs);