Seccomp Profile
On Linux, go-judge applies an embedded, architecture-aware seccomp filter to sandbox workloads by default. The filter is based on a vendored snapshot of Moby's default profile, then converted and tightened for go-judge. It has a default action of errno: syscalls outside the allowlist fail with an error. A denied syscall normally causes the command to finish with status Dangerous Syscall.
When the filter is applied
The container init process completes namespace, filesystem, and cgroup setup before installing the filter. Workload processes inherit it when they start; go-judge does not install a separate filter for every command. The init setup can use operations such as clone, clone3, unshare, and kill before the workload filter is installed.
The generated profile has shared rules plus architecture-specific syscall rules for x86-64, i386, AArch64, and ARM. Syscall names are resolved for each architecture when the profile is generated and loaded.
Why the profile differs from Moby's baseline
The converter removes Moby rules that depend on container capabilities. go-judge drops capabilities before executing submitted programs, so those conditional rules do not describe the workload's effective permissions. Architecture selectors are resolved into explicit per-architecture rules.
The policy also removes syscall groups that were absent from the compiler and runtime workloads used to build the profile and that add authority or kernel attack surface:
- Cross-process inspection and control:
ptrace,process_vm_readv,process_vm_writev,process_mrelease, andget_robust_listcan expose or affect other processes. - Alternate executable loading:
execveat,memfd_create, andmemfd_secretadd fileless executable loading or staging paths. - Legacy x86 execution state:
modify_ldt,get_thread_area, andset_thread_areaexpose legacy compatibility interfaces. - Device nodes and filesystem event attachment:
mknod,mknodat, andfanotify_markcan expose devices or monitor filesystem activity beyond ordinary file access. - Cross-process signaling and scheduling:
getsid,rt_sigqueueinfo,rt_tgsigqueueinfo,sched_setattr,sched_setparam, andtkillcan identify or affect other processes.getpgidis restricted to querying the calling process because shells use that form for job control. - Legacy asynchronous I/O:
io_setup,io_submit,io_getevents,io_pgetevents,io_destroy, andio_canceladd an unused I/O interface. - Alternate filesystem and mount interfaces:
openat2,name_to_handle_at,listmount, andstatmountadd interfaces beyond the file operations observed in workloads. - Kernel-mediated data transfer:
copy_file_range,sendfile,splice,tee, andvmspliceprovide descriptor-to-descriptor transfer paths that workloads do not need.
The profile also denies personality and restricts ioctl by blocking terminal input injection and Linux virtual-console requests. Socket creation is limited to AF_UNIX, AF_INET, and AF_INET6; socketpair is limited to AF_UNIX. On i386, seccomp cannot inspect the pointed-to arguments used by the legacy socketcall interface, so its socket and socketpair operations are denied. These rules reduce available kernel interfaces; they do not by themselves provide network namespace isolation.
Allowed syscall list and compiler observations
The lists below are the syscall names present in the current generated profile across its shared and architecture-specific sections. Architecture sections include ABI aliases; a syscall can be unavailable on a different architecture. Several calls have argument filters rather than unrestricted access: socket is limited to AF_UNIX, AF_INET, and AF_INET6; socketpair to AF_UNIX; ioctl excludes TIOCSTI and TIOCLINUX; and getpgid is limited to querying the current process. The i386 socketcall path denies socket creation.
Compiler associations below report observed use in a sample corpus of 16 language configurations, not a guarantee that every feature of each compiler requires only these calls. Most ordinary file, memory, process, identity, and resource calls were seen across the corpus. The upstream observation records calls by language and compile/run phase.
Compiler observations
| Observed workload | Calls that stood out in the trace |
|---|---|
| Go compiler | clone, pidfd_open, pidfd_send_signal, and fallocate appeared during compilation. |
| Java compiler/runtime | socket was used during compile and run. The profile permits only AF_UNIX, AF_INET, and AF_INET6; AF_UNIX and internet-family sockets were observed in Java compilation, and AF_UNIX in runtime. |
| Rust compiler | socketpair(AF_UNIX) appeared during compilation. |
| Other sampled workloads | The common file, memory, process, identity, and resource calls appear across the 16 sampled language configurations. The source observation lists each language and phase separately. |
File and directory operations
_llseek, access, chdir, chmod, chown, chown32, close, close_range, creat, faccessat, faccessat2, fadvise64, fadvise64_64, fallocate, fchdir, fchmod, fchmodat, fchmodat2, fchown, fchown32, fchownat, fcntl, fcntl64, fdatasync, fgetxattr, flistxattr, flock, fremovexattr, fsetxattr, fstat, fstat64, fstatat, fstatat64, fstatfs, fstatfs64, fsync, ftruncate, ftruncate64, getcwd, getdents, getdents64, getxattr, getxattrat, lgetxattr, link, linkat, listxattr, listxattrat, llistxattr, lremovexattr, lseek, lsetxattr, lstat, lstat64, mkdir, mkdirat, newfstatat, open, openat, read, readahead, readlink, readlinkat, readv, removexattr, removexattrat, rename, renameat, renameat2, rmdir, setxattr, setxattrat, stat, stat64, statfs, statfs64, statx, sync, sync_file_range, syncfs, truncate, truncate64, umask, unlink, unlinkat, utime, utimensat, utimensat_time64, utimes, write, writev
Memory management
brk, madvise, mincore, mlock, mlock2, mlockall, mmap, mmap2, mprotect, mremap, mseal, munlock, munlockall, munmap, pkey_alloc, pkey_free, pkey_mprotect, remap_file_pages
Process, thread, and signal control
clone, clone3, execve, exit, exit_group, fork, getpgid, getpgrp, getpid, getppid, gettid, kill, pidfd_open, pidfd_send_signal, prctl, rt_sigaction, rt_sigpending, rt_sigprocmask, rt_sigreturn, rt_sigsuspend, rt_sigtimedwait, rt_sigtimedwait_time64, set_robust_list, set_tid_address, setpgid, setsid, sigaltstack, tgkill, vfork, wait4, waitid, waitpid
Time and timers
alarm, clock_adjtime, clock_adjtime64, clock_getres, clock_getres_time64, clock_gettime, clock_gettime64, clock_nanosleep, clock_nanosleep_time64, getcpu, getrusage, gettimeofday, nanosleep, setitimer, sysinfo, timer_create, timer_delete, timer_getoverrun, timer_gettime, timer_gettime64, timer_settime, timer_settime64, timerfd_create, timerfd_gettime, timerfd_gettime64, timerfd_settime, timerfd_settime64, times
Scheduling and resource limits
getpriority, getrlimit, ioprio_get, ioprio_set, prlimit64, sched_get_priority_max, sched_get_priority_min, sched_getaffinity, sched_getattr, sched_getparam, sched_getscheduler, sched_rr_get_interval, sched_rr_get_interval_time64, sched_setaffinity, sched_setscheduler, sched_yield, setpriority, setrlimit, ugetrlimit
Synchronization, IPC, and polling
epoll_create, epoll_create1, epoll_ctl, epoll_ctl_old, epoll_pwait, epoll_pwait2, epoll_wait, epoll_wait_old, eventfd, eventfd2, futex, futex_requeue, futex_time64, futex_wait, futex_waitv, futex_wake, inotify_add_watch, inotify_init, inotify_init1, inotify_rm_watch, ipc, mq_getsetattr, mq_notify, mq_open, mq_timedreceive, mq_timedreceive_time64, mq_timedsend, mq_timedsend_time64, mq_unlink, msgctl, msgget, msgrcv, msgsnd, pipe, pipe2, poll, pselect6, pselect6_time64, select, semctl, semget, semop, semtimedop, semtimedop_time64, shmat, shmctl, shmdt, shmget, signalfd, signalfd4
Sockets and networking
accept, accept4, bind, connect, getpeername, getsockname, getsockopt, listen, recv, recvfrom, recvmmsg, recvmmsg_time64, recvmsg, send, sendfile64, sendmmsg, sendmsg, sendto, setsockopt, shutdown, socket, socketcall, socketpair
Credentials and system information
capget, capset, getegid, getegid32, geteuid, geteuid32, getgid, getgid32, getgroups, getgroups32, getrandom, getresgid, getresgid32, getresuid, getresuid32, getuid, getuid32, setfsgid, setfsgid32, setfsuid, setfsuid32, setgid, setgid32, setgroups, setgroups32, setregid, setregid32, setresgid, setresgid32, setresuid, setresuid32, setreuid, setreuid32, setuid, setuid32, uname
Architecture-specific and other operations
_newselect, adjtimex, arch_prctl, arm_fadvise64_64, arm_sync_file_range, breakpoint, cacheflush, cachestat, dup, dup2, dup3, futimesat, getitimer, io_pgetevents_time64, ioctl, landlock_add_rule, landlock_create_ruleset, landlock_restrict_self, lchown, lchown32, map_shadow_stack, membarrier, msync, pause, ppoll, ppoll_time64, pread64, preadv, preadv2, pwrite64, pwritev, pwritev2, restart_syscall, rseq, seccomp, set_tls, sigprocmask, sigreturn, symlink, symlinkat, time, unshare, uretprobe
Configuration
Use -seccomp-conf <path> to replace the embedded profile with a custom profile in go-judge's architecture-aware YAML format. Use -no-seccomp to disable the filter for troubleshooting or benchmarking; this removes an isolation layer and should not be used for normal service.
The profile source, generation notes, and implementation rationale are maintained in the go-judge seccomp directory.