pyseccomp
Pyseccomp is a pure Python interface to the libseccomp library, leveraging ctypes to provide syscall filtering capabilities via Linux's seccomp mechanism. It aims for API compatibility with libseccomp's official Python bindings. The library is actively maintained, with its latest release (version 0.1.2) published in January 2021.
Warnings
- breaking Older versions of pyseccomp may have compatibility issues with `libseccomp` versions prior to 2.4, potentially leading to incorrect behavior or crashes.
- gotcha Missing C function prototypes in pyseccomp versions prior to 0.1.1 could lead to segmentation faults when certain library functionalities were invoked.
- gotcha Pyseccomp is a wrapper for the `libseccomp` C library. If `libseccomp` is not installed on the system, pyseccomp will raise a `RuntimeError` during initialization, stating 'Unable to find libseccomp'.
- gotcha Applying seccomp filters too broadly or without a complete understanding of required syscalls can easily break an application, leading to unexpected crashes, hangs, or incorrect behavior. Common omissions include syscalls for file I/O (`openat`, `read`, `write`), process management (`exit_group`), and system information (`stat`).
Install
-
pip install pyseccomp
Imports
- SyscallFilter, ALLOW, LOG, ERRNO
from pyseccomp import SyscallFilter, ALLOW, LOG, ERRNO
Quickstart
import errno
try:
import seccomp
except ImportError:
import pyseccomp as seccomp
def setup_seccomp_filter(log_only: bool = False):
"""
Sets up a basic seccomp filter to restrict process execution.
"""
f = seccomp.SyscallFilter(seccomp.ALLOW)
# Always log, even when returning an error
f.set_attr(seccomp.Attr.CTL_LOG, 1)
# Define action: LOG for logging or ERRNO(EACCES) for denying and returning EACCES
action = seccomp.LOG if log_only else seccomp.ERRNO(errno.EACCES)
# Deny execution of new processes
f.add_rule(action, "execve")
f.add_rule(action, "execveat")
f.add_rule(action, "vfork")
f.add_rule(action, "fork")
f.load()
print(f'Seccomp filter enabled with action: {"LOG" if log_only else "ERRNO(EACCES)"}')
if __name__ == "__main__":
print("Applying seccomp filter to prevent fork/execve...")
setup_seccomp_filter(log_only=False)
# Attempt to fork (this should be blocked by seccomp)
try:
import os
pid = os.fork()
if pid == 0:
print("Child process created (THIS SHOULD NOT HAPPEN IF SECCOMP WORKS!)")
os._exit(0)
else:
print(f"Parent process: Child PID {pid}")
os.waitpid(pid, 0)
except OSError as e:
print(f"Fork failed as expected due to seccomp: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")
print("Filter applied. Program will now exit.")