Master the fundamental concepts of system calls & kernel interface through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksseccomp-bpf installs a bytecode program the kernel runs on every syscall. Allow read/write, deny execve, and untrusted code cannot spawn shells even with memory corruption.
Typical sandbox:
SECCOMP_RET_ALLOW or SECCOMP_RET_KILLFor example, a JSON parser sandbox might allow read, write, exit_group, brk, mmap and trap on socket.
seccomp-bpf is the exact mechanism behind Chrome's renderer sandbox, Docker's default seccomp profile, and systemd's SystemCallFilter=, all of which whitelist a minimal syscall set to shrink the kernel's attack surface for untrusted code. Getting the BPF comparison direction wrong here is a real security bug class: an inverted allow/deny check has shipped in real sandbox escapes, which is why filters are almost always reviewed line-by-line before merging.
Before you call the implementation done, walk failure modes on purpose. Test empty structures, single-element edge cases, maximum concurrency, and errno paths that must not crash the program. OS code usually fails in production when happy-path tests pass but invariants break under contention or memory pressure.
Keep structures small and name fields after kernel counterparts when possible. That lets you read man pages and kernel source side by side while you work. Print observable events during development; remove noisy logs once tests pass reliably.
You will write a seccomp-bpf filter, apply it with prctl, and demonstrate a blocked syscall. The task asks you to log the signal delivered when a forbidden syscall is attempted.
seccomp-bpf sandboxes a process with a tiny classic-BPF program that the kernel runs on every system call. The program reads struct seccomp_data and returns an action (allow, fail with an errno, kill, and so on). Write the verifier and the interpreter for that program. The verifier applies the kernel's checks, and the interpreter evaluates test syscalls against an accepted filter.
A program, one instruction per line, then end, then test lines. A ; starts a comment.
cLoading…
Numbers may be decimal or 0x hex. seccomp_data is 64 bytes, read as 32-bit little-endian words: nr at offset 0, arch at 4, the instruction pointer at 8, and args[i] at 16 + 8*i (low word), with its high word at 20 + 8*i. The ARCH values are x86_64 0xc000003e, i386 0x40000003 and aarch64 0xc00000b7.
line N: cannot parse "TEXT" (N counts every input line; TEXT has comments and surrounding space removed). If there was any such line, print rejected: parse errors at end.rejected: empty programrejected: insn I: ld [K] is outside struct seccomp_data or misaligned (K must be a multiple of 4 and below 64)rejected: insn I: jump out of range (every jump target must be a later instruction inside the program)rejected: last instruction is not retaccepted: N instructions.0x80000000 KILL_PROCESS, 0 KILL_THREAD, 0x00030000 TRAP, 0x00050000 ERRNO(data), 0x7ff00000 TRACE, 0x7ffc0000 LOG and 0x7fff0000 ALLOW. Any other value is KILL_PROCESS (unknown action 0x........). ERRNO adds the name for 1 EPERM, 13 EACCES and 38 ENOSYS.-> no filter installed, ALLOW. An unknown ARCH prints test: unknown arch NAME.cLoading…
The syscall name is shown only for x86_64 numbers: read 0, write 1, open 2, close 3, mmap 9, getpid 39, socket 41, execve 59, exit 60, exit_group 231 and openat 257. The count is the number of instructions executed, including the ret.
Input:
cLoading…
Output:
cLoading…
seccomp_data image for each test, and let ld [K] index it. Do not special-case the fields.ret, an accepted filter always terminates.Hidden tests cover a verifier rejection, tests against a rejected filter, ret a, ja, and/or masking, every action kind including an unknown one, filters on the high word of a 64-bit argument, and the aarch64 architecture check.