CECCOMP(1)
π NAME π
CECCOMP(1) β from the Ceccomp Manual. ceccomp β a tool to analyze seccomp filters β¨
πΈ SYNOPSIS πΈ
usage: ceccomp <asm|disasm|emu|trace|probe|version|help> [FILE] [-q|--quiet]
[-f|--format FMT] [-a|--arch ARCH] [-p|--pid PID] [-s|--seize]
[-o|--output FILE] [-c|--color WHEN] ...
π¦ CONCEPT π¦
Okay so bestie, the kernel uses BPF filters to limit syscall rules, and those get applied via the seccomp or prctl syscall. For example, down below is a simple filter to block the execve syscall in hex format:
1: 20 00 00 00 00 00 00 00 $A = $syscall_nr
2: 15 00 00 01 3b 00 00 00 if ($A != execve) goto 4
3: 06 00 00 00 00 00 00 00 return KILL
4: 06 00 00 00 00 00 ff 7f return ALLOW
The hex part is what the kernel received, and ceccomp takes it and disassembles it back to human readable text β for instance, the lineno on the left and the statement on the right π
Important: Later Iβll useTEXTin short for BPF human readable text, and useRAWin short for BPF raw format, please keep that in mind.
π DESCRIPTION π
ceccomp has 5 main functions. Basically itβs a C version of seccomp-tools, however, there are some breaking changes you need to know, which will be highlighted in each subcommand section π₯
π§ asm - ASSEMBLE π§
ceccomp asm [-c WHEN] [-a ARCH] [-f FMT] [TEXT]
Assemble TEXT to RAW. Use it to embed hand written filter rules into C code or to see the original code of some TEXT π«Ά
-c,--color WHENβ Determines when to display warnings and errors in color. If the value isauto,ceccompwill display color when the output target is a βttyβ. Can beauto,neveroralways. The default value isauto.-a,--arch ARCHβ Set to any architecturelibseccompsupports. Will be used to determine the actual syscall number behind the name (for example, onx86_64, you could write"execve"instead of59like the basic example above). Your system arch will be taken if not set viauname. The default value on your system isx86_64.-f,--format FMTβ Determines howceccompproduces binary-format bpf code. Can behexfmt,hexline,raworc-macro. You could find sample output inEXAMPLESsection. The default value ishexline.TEXTβ Take an optional filename to determine which file containingTEXTwill be assembled. Will read from stdin if not set.-is treated as stdin.
Important: The assembly syntax was changed greatly since version 4.0, please checkout grammar reference below!
Please check out TEXT GRAMMAR REFERENCE section to see how to write a rule by hand. Some examples will be displayed in EXAMPLES section.
Note: Since version 4.0, endianness is considered. If target endiannessARCHis different from machine endianness, the filters will be reversed (CODEandK) before outputting.
Note: Since version 4.3, a newFMTc-macrois added to port seccomp rules to other architectures easily.
Whatβs different vs seccomp-tools? π
seccomp-tools asmβ Use its own grammar to assemble, a bit script like; can assemble invalidTEXTwhich will be rejected by kernel.ceccomp asmβ You can just takedisasmoutput toasm, no new grammar is needed to learn; take stdin as input by default.
π disasm - DISASSEMBLE π
ceccomp disasm [-c WHEN] [-a ARCH] [-e] [RAW]
Disassemble RAW to TEXT. Use it to see what a filter does if you could not access the filter via trace and have to manually extract the filter out π
-c,--color WHENβ Argument description can be found inasm - ASSEMBLEsection.disasmmay print more text in color including syntax highlighting forTEXT.-a,--arch ARCHβ Set to any architecturelibseccompsupports. Will be used to determine how filtered syscall number inRAWfilter is translated to syscall name (for example, onx86_64, the number0x3bis translated toexecveif is comparingsyscall_nr, see the basic example above). The default value on your system isx86_64.-e,--ebpfβ TreatRAWas eBPF insn bytes instead of cBPF filter bytes. This flag is designed to test whether eBPF-to-cBPF conversion is working or not. To use this function, please dump installed eBPF insns migrated from seccomp filters in a process via eBPF or a kernel module. Any input not generated by kernel may lead to undefined behavior.RAWβ A binary file with raw BPF codes. Takes stdin as input if not set. Treat-as stdin. The file is arch-revelent, so it may not be portable on different archs.
Note: Since version 4.0, endianness is considered. If target endiannessARCHis different from machine endianness, the filters will be reversed (CODEandK) before decoding.
Note:ceccompwill try to resolve syscall number under an arch ONLY IF that at that line, arch can be determined. On foreign arch (not equal to the arch you set), the foreign arch will be prepended to syscall name. You may notice that in some cases,seccomp-toolsis able to resolve the name whilececcompis not, that may be intended as the arch is not determined.
Whatβs different vs seccomp-tools? π«Ά
seccomp-tools disasmβ Disassembles in its format; never check if the filter is valid.ceccomp disasmβ Disassembles inceccompformat, and takes stdin as input by default; check arch strictly and always display foreign arch name.
π emu - EMULATE π
ceccomp emu [-c WHEN] [-a ARCH] [-q] TEXT SYSCALL_NAME/SYSCALL_NR [ARGS[0] ARGS[1] ... ARGS[5] PC]
Emulate what will happen if syscall(SYSCALL_NR, ARGS[0], ARGS[1], ..., ARGS[5]) from PC is called following rules described in TEXT. Use it to see the result without actually running it in a program, or when you donβt want to examine the filter rule manually. This subcommand can be used to automatically examining a filter β¨
-c,--color WHENβ Argument description can be found inasm - ASSEMBLEsection.emumay print more text in color including syntax highlighting forTEXTand skipped statements.SYSCALL_NAME/SYSCALL_NRβ If you setSYSCALL_NAME(likeexecve), it will be translated toSYSCALL_NRunderARCHfirst. Or else setSYSCALL_NRdirectly (like59). Then the nr will be tested against the bpf filter to see the result of that syscall. This argument is NOT optional.ARGS[0-5]andPCβ Register values when calling syscall. For example, onx86_64, these are equivalent tordi,rsi,rdx,r10,r8,r9andrip. Their default value is0.-a,--arch ARCHβ Argument description can be found inasm - ASSEMBLEsection.TEXTβ Take a filename to determine which file containingTEXTrule will be tested. Note that filename CAN NOT be ignored asceccompcan not determine if a positional argument is syscall or filename. Use-to refer to stdin.-q,--quietβ Only print the eval result of the filter. For example, if last statement emulated isreturn KILL, thenKILLis printed.
Whatβs different vs seccomp-tools? π
seccomp-tools emuβ Take aRAWas input.ceccomp emuβ Take aTEXTas input and take stdin as input by default; setPCis possible.
π₯ trace - TRACE FILTER IN RUNTIME π₯
ceccomp trace [-c WHEN] [-q] [-o FILE] PROGRAM [program-args]
[-c WHEN] [-q] -p PID [-s]
The first line captures filters PROGRAM loads in runtime by tracing it; the second line extract seccomp filters from PID, or trace PID to capture subsequent seccomp filters; once fetched filters, print them in TEXT. You can only choose one of the two formats above. Use this if running the program is the simplest way to fetch bpf filters or a program with seccomp filters installed is waiting for input.
-c,--color WHENβ bestie, the arg deets for this one live in the asm - ASSEMBLE section.tracecan print more text in color, including syntax highlighting forTEXT.-o,--output FILEβ lowkey useful whenPROGRAMproduces quite a lot output in stderr.ceccompcan close stdin and stdout to limitPROGRAMinput and output, soceccompuses stderr to print messages when runningPROGRAM; setFILEif you want to seeTEXTin some other file. Treat-as stdout.PROGRAMβ set this to the program you want to run, andprogram-argsare its arguments, just like running shell commandexec PROGRAM program-args.-p,--pid PIDβ set to the pid you want to inspect.PIDconflicts withPROGRAM; you can either run a program dynamically or examine a pid in one command. Without the-sflag, trace pid will try to extract the seccomp filter inPIDviaptrace(PTRACE_SECCOMP_GET_FILTER), which may not be available in some systems. The pid here is actually process (thread) id β you can trace a thread or process.-s,--seizeβ ONLY AVAILABLE FOR TRACE PID MODE. Setting this flag overrides trace pid behavior to attach toPIDand keep tracing for seccomp filter loading like trace prog mode. This flag was introduced in version 4.0.-q,--quietβ set to suppress the extra[INFO]prints when detecting process forking, exiting or seccomp filter loading. This flag was introduced in version 4.0.
Note β To extract filters fromPID,CAP_SYS_ADMINis needed (without the-sflag) andCAP_SYS_PTRACEmay also be needed. The easiest way to acquire them is callingceccompwithsudo.
Note β Since version 3.1, multiple process tracing is introduced, and when tracee forking/resolving/exiting, an extraINFOmessage is printed. You can discard it by running command likececcomp trace -q PROG 2>/dev/null.
Note β Since version 4.2,dumpsub command is added as an alias oftrace, to keep compatibility withseccomp-tools.
If you're coming from seccomp-tools dump, here's the tea on the differences:
seccomp-tools dumpβ Setting output format is possible; each filter can be output to a different file; killingPROGRAMonce LIMIT times of filters loaded; wrappingPROGRAMinsh -c.ceccomp traceorceccomp dumpβ All filters are output to a single file; never killPROGRAM;PROGRAMis launched directly, so./is not needed; explicitly print when forking; able to attach to pid for dynamic seccomp filter capturing.
πΈ probe - TEST COMMON SYSCALLS INSTANTLY πΈ
ceccomp probe [-c WHEN] [-o FILE] [-q] PROGRAM [program-args]
Run PROGRAM with program-args to capture the FIRST seccomp filter, and then kill all children. Use it when you need a quick check against a program, and to detect potential seccomp rule issues.
All argument descriptions can be found in the trace - TRACE FILTER IN RUNTIME section.
The output for this subcommand is the emulating result of common syscalls like execve, open and so on. If the filter itself is not capable of blocking syscalls, you could know that with a glance. π
Typical output for this subcommand is described below; more detailed example could be found in EXAMPLES section.
open -> ALLOW
read -> ALLOW
write -> ALLOW
execve -> KILL
execveat -> KILL
mmap -> ALLOW
mprotect -> ALLOW
openat -> ALLOW
sendfile -> ALLOW
ptrace -> ERRNO(1)
fork -> ALLOW
Note β seccomp-tools donβt have this subcommand.
π§ capture - CAPTURE FILTERS WITH EBPF π§
ceccomp capture [-c WHEN] [-p PID]
Capture seccomp filters in global scope if PID is not set. The eBPF program will trace the seccomp_check_filter kernel function, reliably intercepting seccomp filters that the kernel will load, WITHOUT race conditions compared to trace - TRACE FILTER IN RUNTIME. This function is named "global capture" below. Linux 5.15 is the lowest recommended kernel version to run this function on x86_64; other architecture may require a higher kernel version to run this function.
If PID is set, an eBPF program to extract installed seccomp filters in the corresponding process (actually thread) will be installed. Note that inside kernel, pid is referred thread id and tgid is referred to process id. The eBPF program directly pulls eBPF insns migrated from original seccomp filters out and converts them back to perform disasm - DISASSEMBLE. This function does not require CONFIG_CHECKPOINT_RESTORE kernel config, and is functional even if ceccomp itself is under seccomp. This function is named "capture pid" below. Linux 6.2 is the lowest kernel version to run this function, as bpf_task_from_pid was introduced then.
Important β When the kernel migrates seccomp filters, the conversion from cBPF to eBPF is lossy because several distinct cBPF instructions can be mapped to the same eBPF instruction sequence. As a result, the output from "capture pid" may not be identical to the original seccomp filter, even though it is functionally equivalent.
Currently, compat task detection is only supported on x86_64 and aarch64. With this feature, ceccomp can identify whether a task is native (64-bit task on 64-bit kernel) or "compatible" (32-bit task on 64-bit kernel), so that ceccomp can pass the correct architecture token to libseccomp to query syscall name in captured seccomp filters.
Note that eBPF utilizes asynchronous ring buffer to send back data to user-mode process, so if lots of seccomp filters are loaded at the same time, the buffer may run out and you need to see detailed errors via bpftool prog trace. Since we canβt send the errors back through full ring buffer, those overflowed filters are actually invisible to users without reading kernel messages.
-c,--color WHENβ argument description can be found in the asm - ASSEMBLE section.-p,--pid PIDβ which process (thread) to extract seccomp filter insns from.
Tip β All PID presented in either "global capture" or "capture pid" are INITIAL NAMESPACE PID, not PID in current namespace. Itβs recommended that only run ceccomp capture in initial namespace.
Note β This module is optional, you can opt it out during configuration. This module require libbpf to work.
Note β This subcommand was introduced in version 4.3.
π TEXT GRAMMAR REFERENCE β¨
Important π¨ bestie read this first!! The grammar changed greatly since version4.0β we refactored the lexer for better human readability. The wrapper is now prefixed by#because it's a comment now. Andlineis replaced bylabel, so now the lexer depends on label declaration to decide where to jump, instead oflinenoin the TEXT file. It's giving glow-up, honestly.
A valid TEXT format is described in an EBNF-like declaration right here: https://github.com/ceccomp/ceccomp/issues/17#issuecomment-3610531705 β but if you have no interest in knowing what EBNF even is (valid, no judgement π«Ά), please keep reading for examples.
BPF ops which are not described below are banned by the kernel. Like, kernel said no and it meant it π.
π¬ Comment and Label
ceccomp disasm displays a lot of things, but some of them are optional for asm.
#Label CODE JT JF K
#---------------------------------
L0001: 0x06 0x00 0x00 0x7fff0000 return ALLOW
#---------------------------------
Any text after # will be discarded by asm, like some script languages. Iconic behaviour tbh.
Empty lines are accepted. Live your truth, add blank lines πΈ.
Label declaration is an identifier at the beginning of the line and suffixed by : like L0001. An identifier is a string that starts with alpha and contains only alphanumeric characters and underscore _. Label is only necessary if it's the destination of goto β those redundant labels added by disasm are just for readability. E.g. in if ($A == 0) goto somewhere, somewhere is a label and must be declared after the statement. Label declaration can take a line separately, or be put in front of the statement.
The CODE, JT, JF and K value generated by disasm will be discarded by asm β asm only parses the effective statement after K. So don't stress about them π
.
Caution β οΈ There are some slight differences betweenceccomp disasmandseccomp-tools disasm, down below is a general example. And some statements are different, so don't pipeseccomp-toolsoutput toceccompblindly. Fr fr, that's a trap π.line CODE JT JF K ================================= 0000: 0x06 0x00 0x00 0x7fff0000 return ALLOW
π Assignment
A can be set to seccomp attributes directly. But X can not be assigned seccomp attributes directly, due to kernel limit. Sorry bestie, kernel said no π.
$A = $arch
$A = $syscall_nr
To assign A with those 64-bit long fields, a low_ or high_ prefix is needed.
$A = $low_pc
$A = $high_pc
$A = $low_args[0]
$A = $high_args[0]
...
$A = $low_args[5]
$A = $high_args[5]
A special attribute is sizeof(struct seccomp_data), and that one can be assigned to A or X directly π«Ά:
$A = $scmp_data_len
$X = $scmp_data_len
Temporary memory is 32-bit β to access it, you can use hex or dec as index. Both A and X are assignable. Assigning immediate values to A or X accepts any format of number, as long as you imply the correct base with "0x" or "0b".
$X = $mem[0]
$A = $mem[0xf]
$A = $mem[15] # both hex and dec index are OK
$A = 0
$X = 0x3b
$A = 0b1111
$A = 0333
You could also assign X to A, or in the reverse order. Assigning X or A to temporary memory is definitely okay π
$A = $X
$X = $A
$mem[3] = $X
$mem[0x4] = $A
β Arithmetic Operations
Various operations can be applied to A. Math class but make it seccomp π§:
$A += 30
$A -= 4
$A *= 9
$A /= 1
$A &= 7
$A >>= 6
The right value can be X too, bestie:
$A &= $X
$A |= $X
$A ^= $X
$A <<= $X
And there is a way to negativate A:
$A = -$A
β¬οΈ Jump Downwards If ...
Unconditional jump, no thoughts head empty:
goto L3
Jump if:
if ($A == execve) goto L3
if ($A != 1234) goto L4
if ($A & $X) goto L5
if !($A & 7) goto L6
if ($A <= $X) goto L7
If true jump to ... if false jump to...:
if ($A > $X) goto L3, else goto L4
if ($A >= 4567) goto L5, else goto L6
ONLY in conditions, you CAN replace a number with a syscall name or arch name. In the examples above, 0x3b is replaced by execve. All the syscall names will be resolved to syscall number under your selected arch. If you want to resolve a syscall name in a foreign arch (not equal to your selected arch), please prepend an arch and a dot. For example, your arch is x86_64, and you are writing aarch64 rules, then please write like:
if ($A == aarch64.read) goto 5
Note that if you manually set arch to aarch64 with -a aarch64, you can omit aarch64. in the statement. Convenience slay β¨.
π Return Code
Return value of register A:
return $A
Or return an immediate value, with an extra field in (). Actions including TRACE, TRAP and ERRNO accept an extra field β without (), they are treated as action(0).
return 0x13371337
return KILL
return KILL_PROCESS
return TRAP(123)
return ERRNO(0)
return TRACE
return TRACE(3)
return LOG
return NOTIFY
π Short Example
The following TEXT is valid for asm, which blocks execve and execveat for amd64 syscalls. Little baby example, so cute:
$A = $syscall_nr
if ($A == execve) goto forbid
if ($A == execveat) goto forbid
return ALLOW
forbid: return KILL
π§ RESTRICTIONS
ceccomp asm puts some restrictions on TEXT for better performance. Rules are rules bestie π
:
'\0'must not be found in TEXT since it's a text file.- A line must be shorter than
384bytes. - A TEXT file must have less than
16384lines. - A TEXT file must be smaller than
4 MiB.
And for both asm and disasm, effective statements (that can be encoded or decoded into BPF) must be less or equal than 4096 β this is enforced by kernel. Kernel stays enforcing, periodt π.
A fun fact about ceccomp asm: any basic ANSI color in a TEXT file, e.g., \x1b[31m, will be discarded when processing. So your pretty rainbow colors get absolutely humbled ππ.
π EXAMPLES
Manpage can not display images, so please check out the html version of this page to see examples. The terminal simply does not have the range, ngl π¦.
π REPO
Visit https://github.com/ceccomp/ceccomp to find the code. Pull Requests and Issues are welcome!
Copyright Β© 2025-present, distributed under GPLv3 or later.
π AUTHORS
dbgbgtf
RocketDev
π that's the whole page bestie π this was ceccomp 4.3.1, dated 2026-10-11 β go forth and write the cleanest seccomp filters of your life, i'm literally obsessed with you πβ¨π¦
π¦ where this page comes from
- arch rolling: ceccomp 4.3.1-1 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms