From 732e7c06812e6e2ceb4044ec8d524aa934e1017b Mon Sep 17 00:00:00 2001 From: David Roberts Date: Fri, 4 Jan 2019 15:04:15 +0000 Subject: [PATCH] [ML] Update seccomp filter for Fedora 29 Fedora 29 uses different system calls to platforms we've previously tested on, and hence suffers from certain functionality failing due to the seccomp filter. This commit permits 3 additional system calls: 1. __NR_gettimeofday 2. __NR_unlinkat 3. __NR_getdents64 (It is likely that other Linux distributions using modern glibc would also hit one or more of these system calls. Non-fatal problems probably got progressively worse in the lead up to the fatal problem that surfaced in Fedora 29.) Fixes #350 Backport of #354 --- docs/CHANGELOG.asciidoc | 16 +++++++++ lib/seccomp/CSystemCallFilter_Linux.cc | 47 ++++++++++++-------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 3555e25d99..a73e4f8f48 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -28,6 +28,22 @@ //=== Regressions + == {es} version 6.7.0 + +=== Breaking Changes + +=== Deprecations + +=== New Features + +=== Enhancements + +Adjust seccomp filter for Fedora 29. {ml-pull}354[#354] + +=== Bug Fixes + +=== Regressions + == {es} version 6.6.0 === Breaking Changes diff --git a/lib/seccomp/CSystemCallFilter_Linux.cc b/lib/seccomp/CSystemCallFilter_Linux.cc index 593e012388..25ed339c18 100644 --- a/lib/seccomp/CSystemCallFilter_Linux.cc +++ b/lib/seccomp/CSystemCallFilter_Linux.cc @@ -26,8 +26,6 @@ const std::uint32_t UPPER_NR_LIMIT = 0x3FFFFFFF; // Offset to the nr field in struct seccomp_data const std::uint32_t SECCOMP_DATA_NR_OFFSET = 0x00; -// Offset to the arch field in struct seccomp_data -const std::uint32_t SECCOMP_DATA_ARCH_OFFSET = 0x04; // Copied from seccomp.h // seccomp.h cannot be included as it was added in Linux kernel 3.17 @@ -44,37 +42,36 @@ const std::uint32_t SECCOMP_DATA_ARCH_OFFSET = 0x04; #endif const struct sock_filter FILTER[] = { - // Load architecture from 'seccomp_data' buffer into accumulator - BPF_STMT(BPF_LD | BPF_W | BPF_ABS, SECCOMP_DATA_ARCH_OFFSET), - // Jump to disallow if architecture is not X86_64 - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 0, 5), // Load the system call number into accumulator BPF_STMT(BPF_LD | BPF_W | BPF_ABS, SECCOMP_DATA_NR_OFFSET), // Only applies to X86_64 arch. Jump to disallow for calls using the x32 ABI - BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, UPPER_NR_LIMIT, 36, 0), + BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, UPPER_NR_LIMIT, 39, 0), // If any sys call filters are added or removed then the jump // destination for each statement including the one above must // be updated accordingly // Allowed sys calls, jump to return allow on match - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_read, 36, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_write, 35, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_writev, 34, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_lseek, 33, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_lstat, 32, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_clock_gettime, 31, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_readlink, 30, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_stat, 29, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_fstat, 28, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_open, 27, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_close, 26, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_connect, 25, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_clone, 24, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_statfs, 23, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_dup2, 22, 0), - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mkdir, 21, 0), // for forecast temp storage - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_rmdir, 20, 0), // for forecast temp storage - BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_getdents, 19, 0), // for forecast temp storage + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_read, 39, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_write, 38, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_writev, 37, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_lseek, 36, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_lstat, 35, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_clock_gettime, 34, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_gettimeofday, 33, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_readlink, 32, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_stat, 31, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_fstat, 30, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_open, 29, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_close, 28, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_connect, 27, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_clone, 26, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_statfs, 25, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_dup2, 24, 0), + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_mkdir, 23, 0), // for forecast temp storage + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_rmdir, 22, 0), // for forecast temp storage + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_unlinkat, 21, 0), // for forecast temp storage + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_getdents, 20, 0), // for forecast temp storage + BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_getdents64, 19, 0), // for forecast temp storage BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_openat, 18, 0), // for forecast temp storage BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_tgkill, 17, 0), // for the crash handler BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_rt_sigaction, 16, 0), // for the crash handler