Configuring and Troubleshooting Seccomp

Note

This guide and all supporting examples have been constructed for standard RHEL 8 deployment. Please be aware that differences may exist, especially with regards to any audit logging.

Understanding Seccomp

Important

Fundamentally, filtering specific system calls or restricting available privileges is a decision that the administrator of the host machine must make. Disabling or easing restrictions can make a lot of sense when Jacamar CI is being used within a more limited environment as a tool to ease previously manual testing operations amongst trusted users/codes. However, as you open the envelope of accepted users/codes then there remains a benefit to take advantage of such features within the scope of deployment requirements.

To understand seccomp(2) it is best to defer to the appropriate manual for your environment. Jacamar CI offers the ability to configure filters for specific system calls and restrict privileges for CI/CD workflows via the seccomp configuration. The goal is offer the ability to meet a wide range of potential deployment requirements on a system-by-system basis.

Default Configurations

In limited cases the jacamar-auth application will attempt to enforce default filters when they present a clear security benefit. However, we will attempt to keep these limited and trend towards simply making dangerous configurations impossible (i.e., running setuid in an interactive terminal session).

No New Privileges

To learn more about this please review the kernel user-space API guide covering no_new_privs. The keys portion of that document relating to seccomp is:

“Filters installed for the seccomp mode 2 sandbox persist across execve and can change the behavior of newly-executed programs. Unprivileged users are therefore only allowed to install such filters if no_new_privs is set.”

This specific limitation can present hurdles to realizing desired functionality in unique deployment situations. However, if you wish to run seccomp the only way to avoid this limitation is by ensuring the jacamar-auth application has the CAP_SYS_ADMIN capabilities(7) (or the user is already root) and defining the disable_no_new_privs configuration:

[auth.seccomp]
block_all = true
allow_calls = [...]
disable_no_new_privs = true

If seccomp is either explicitly disabled or no rules have been applied then no_new_privs will remain off, unless otherwise configured:

[auth]
no_new_privs = true

This option will utilize prctl(2) to PR_SET_NO_NEW_PRIVS prior to downscoping.

Testing your Configuration

Testing your configuration against specific applications/workflows is easily accomplished via self-compiled application in the Jacamar CI project: tools/seccomp-tester.

This application allows for testing Seccomp filters and related capability restrictions in a limited fashion. Valid Jacamar CI configurations are used in conjunction with arbitrary command execution directly via the CLI without the need to deal with complicated deployments, downscoping, or CI pipelines.

$ cat /example/file/jacamar.toml
[auth.seccomp]
disabled = false
block_all = true
allow_calls = [ "mkdir", "poll", ...]

$ ./seccomp-tester -cfg /example/file/jacamar.toml /usr/bin/scheduler --args
Segmentation fault (core dumped) ...

See the README.md for complete details.

Troubleshooting Seccomp Filters

Important

This section of the guide has been written for Linux Kernel versions 4.14+ as to benefit from a range of enhancements made to seccomp(2). For any issues with logging please first refer to the manual for your deployment and the related “Audit logging of seccomp actions” section.

Blocked Actions

By default any thead that breaks a defined system call filter will be terminated. In addition, whenever possible (i.e., libseccomp API level 3+) those actions will be logged. For example, if we observe the failure via the CI job log:

Getting source from Git repository
/.../get_sources.bash: line 31: 12345 Bad system call (core dumped) mkdir -p "/.../ci-scratch-space.tmp"
Error encountered during job: exit status 1
Error encountered during job: Error executing run_exec: exit status 1

Then utilizing ausearch(8) we are able to query auditd for complete details:

$ sudo ausearch -p 12345 -m SECCOMP
----
time->Tue Jun 14 18:31:19 2022
type=SECCOMP msg=audit(1655245879.115:261): auid=2001162 uid=1000 gid=1000 ses=3 pid=12345 comm="mkdir" exe="/usr/bin/mkdir" sig=31 syscall=83

Allowed Actions

It is also possible to enable more extensive logging that will capture all allowed actions as well:

[auth.seccomp]
log_allowed_actions = true

Please be aware that this setting will extensively utilize your audit log. It is not suited for production environments.