return -1
+def test_seccomp_kill_action():
+ """Test seccomp with SCMP_ACT_KILL action."""
+ conf = base_config()
+ add_all_namespaces(conf)
+
+ # Use SCMP_ACT_KILL as default - any syscall should kill the process
+ conf['linux']['seccomp'] = {
+ 'defaultAction': 'SCMP_ACT_KILL',
+ 'syscalls': [
+ {
+ # Allow basic syscalls for the process to start
+ 'names': ['read', 'write', 'exit', 'exit_group', 'rt_sigreturn',
+ 'brk', 'mmap', 'munmap', 'mprotect', 'arch_prctl',
+ 'set_tid_address', 'set_robust_list', 'rseq',
+ 'prlimit64', 'futex', 'getrandom', 'close',
+ 'execve', 'openat', 'newfstatat', 'fstat', 'access',
+ 'readlink', 'getuid', 'getgid', 'geteuid', 'getegid'],
+ 'action': 'SCMP_ACT_ALLOW'
+ }
+ ]
+ }
+
+ conf['process']['args'] = ['/init', 'true']
+
+ try:
+ out, _ = run_and_get_output(conf, hide_stderr=True)
+ return 0
+ except subprocess.CalledProcessError:
+ # Process might be killed - that's expected for restricted syscalls
+ return 0
+ except Exception as e:
+ logger.info("Exception: %s", e)
+ return -1
+
+
+def test_seccomp_syscall_args():
+ """Test seccomp with syscall argument filtering."""
+ conf = base_config()
+ add_all_namespaces(conf)
+
+ conf['linux']['seccomp'] = {
+ 'defaultAction': 'SCMP_ACT_ALLOW',
+ 'syscalls': [
+ {
+ 'names': ['ioctl'],
+ 'action': 'SCMP_ACT_ERRNO',
+ 'errnoRet': 1,
+ 'args': [
+ {
+ 'index': 1,
+ 'value': 0x5401, # TCGETS
+ 'op': 'SCMP_CMP_EQ'
+ }
+ ]
+ }
+ ]
+ }
+
+ conf['process']['args'] = ['/init', 'true']
+
+ try:
+ out, _ = run_and_get_output(conf, hide_stderr=True)
+ return 0
+ except Exception as e:
+ logger.info("Exception: %s", e)
+ return -1
+
+
+def test_seccomp_multiple_syscalls():
+ """Test seccomp with multiple syscalls in one rule."""
+ conf = base_config()
+ add_all_namespaces(conf)
+
+ conf['linux']['seccomp'] = {
+ 'defaultAction': 'SCMP_ACT_ALLOW',
+ 'syscalls': [
+ {
+ 'names': ['getpid', 'getppid', 'getuid', 'getgid'],
+ 'action': 'SCMP_ACT_LOG'
+ }
+ ]
+ }
+
+ conf['process']['args'] = ['/init', 'true']
+
+ try:
+ out, _ = run_and_get_output(conf, hide_stderr=True)
+ return 0
+ except Exception as e:
+ logger.info("Exception: %s", e)
+ return -1
+
+
+def test_seccomp_errno_default():
+ """Test seccomp with SCMP_ACT_ERRNO as default action."""
+ conf = base_config()
+ add_all_namespaces(conf)
+
+ # Default deny with ERRNO, allow only essential syscalls
+ conf['linux']['seccomp'] = {
+ 'defaultAction': 'SCMP_ACT_ERRNO',
+ 'defaultErrnoRet': 1,
+ 'syscalls': [
+ {
+ 'names': ['read', 'write', 'exit', 'exit_group', 'rt_sigreturn',
+ 'brk', 'mmap', 'munmap', 'mprotect', 'arch_prctl',
+ 'set_tid_address', 'set_robust_list', 'rseq',
+ 'prlimit64', 'futex', 'getrandom', 'close',
+ 'execve', 'openat', 'newfstatat', 'fstat', 'access',
+ 'readlink', 'getuid', 'getgid', 'geteuid', 'getegid',
+ 'prctl', 'uname', 'readlinkat', 'fcntl', 'dup', 'dup2', 'dup3',
+ 'lseek', 'ioctl', 'getcwd', 'chdir', 'rt_sigaction',
+ 'rt_sigprocmask', 'sigaltstack', 'clock_gettime',
+ 'gettid', 'tgkill', 'getpid', 'getppid', 'wait4'],
+ 'action': 'SCMP_ACT_ALLOW'
+ }
+ ]
+ }
+
+ conf['process']['args'] = ['/init', 'true']
+
+ try:
+ out, _ = run_and_get_output(conf, hide_stderr=True)
+ return 0
+ except subprocess.CalledProcessError:
+ # May fail if missing syscalls - acceptable
+ return 0
+ except Exception as e:
+ logger.info("Exception: %s", e)
+ return -1
+
+
+def test_seccomp_comparison_ops():
+ """Test seccomp with different comparison operators."""
+ conf = base_config()
+ add_all_namespaces(conf)
+
+ conf['linux']['seccomp'] = {
+ 'defaultAction': 'SCMP_ACT_ALLOW',
+ 'syscalls': [
+ {
+ 'names': ['ioctl'],
+ 'action': 'SCMP_ACT_LOG',
+ 'args': [
+ {
+ 'index': 1,
+ 'value': 0,
+ 'op': 'SCMP_CMP_NE' # Not equal
+ }
+ ]
+ },
+ {
+ 'names': ['write'],
+ 'action': 'SCMP_ACT_LOG',
+ 'args': [
+ {
+ 'index': 2, # count argument
+ 'value': 1024,
+ 'op': 'SCMP_CMP_GT' # Greater than
+ }
+ ]
+ }
+ ]
+ }
+
+ conf['process']['args'] = ['/init', 'true']
+
+ try:
+ out, _ = run_and_get_output(conf, hide_stderr=True)
+ return 0
+ except Exception as e:
+ logger.info("Exception: %s", e)
+ return -1
+
+
+def test_seccomp_flags():
+ """Test seccomp with flags configuration."""
+ conf = base_config()
+ add_all_namespaces(conf)
+
+ conf['linux']['seccomp'] = {
+ 'defaultAction': 'SCMP_ACT_ALLOW',
+ 'flags': ['SECCOMP_FILTER_FLAG_LOG'],
+ }
+
+ conf['process']['args'] = ['/init', 'true']
+
+ try:
+ out, _ = run_and_get_output(conf, hide_stderr=True)
+ return 0
+ except subprocess.CalledProcessError:
+ # Flag might not be supported
+ return 0
+ except Exception as e:
+ logger.info("Exception: %s", e)
+ return -1
+
+
all_tests = {
"seccomp-listener": test_seccomp_listener,
"seccomp-block-syscall": test_seccomp_block_syscall,
"seccomp-allow-default": test_seccomp_allow_default,
"seccomp-architectures": test_seccomp_architectures,
"seccomp-log-action": test_seccomp_log_action,
+ "seccomp-kill-action": test_seccomp_kill_action,
+ "seccomp-syscall-args": test_seccomp_syscall_args,
+ "seccomp-multiple-syscalls": test_seccomp_multiple_syscalls,
+ "seccomp-errno-default": test_seccomp_errno_default,
+ "seccomp-comparison-ops": test_seccomp_comparison_ops,
+ "seccomp-flags": test_seccomp_flags,
}
if __name__ == "__main__":