README.md
1# Minijail tools
2
3## generate_seccomp_policy.py
4
5This script lets you build a Minijail seccomp-bpf filter from strace output.
6This is very useful if the process that is traced has a fairly tight working
7domain, and it can be traced in a few scenarios that will exercise all of the
8needed syscalls. In particular, you should always make sure that failure cases
9are also exercised to account for calls to `abort(2)`.
10
11If `libminijail` or `minijail0` are used with preloading (the default with
12dynamically-linked executables), the first few system calls after the first call
13to `execve(2)` might not be needed, since the seccomp-bpf filter is installed
14after that point in a sandboxed process.
15
16### Sample usage
17
18```shell
19strace -f -e raw=all -o strace.txt -- <program>
20./tools/generate_seccomp_policy.py strace.txt > <program>.policy
21```
22
23### Using linux audit logs to generate policy
24
25*** note
26**NOTE**: Certain syscalls made by `minijail0` may be misattributed to the
27sandboxed binary and may result in a policy that is overly-permissive.
28Please pay some extra attention when manually reviewing the allowable args for
29these syscalls: `ioctl`, `socket`, `prctl`, `mmap`, `mprotect`, and `mmap2`.
30***
31
32Linux kernel v4.14+ support `SECCOMP_RET_LOG`. This allows minijail to log
33syscalls via the [audit subsystem][1] (Redhat has a nice overview [here][2])
34instead of blocking them. One caveat of this approach is that `SECCOMP_RET_LOG`
35does not log syscall arguments for finer grained filtering.
36The audit subsystem itself has a mechanism to log all syscalls. Though a
37`SYSCALL` event is more voluminous than a corresponding `SECCOMP` event.
38We employ here a combination of both techniques. We rely on `SECCOMP` for all
39except the syscalls for which we want finer grained filtering.
40
41Note that this requires python3 bindings for `auparse` which are generally
42available in distro packages named `python3-audit` or `python-audit`.
43
44#### Per-boot setup of audit rules on DUT
45
46Set up `audit` rules and an empty seccomp policy for later use. This can be
47done in the `pre-start` section of your upstart conf.
48
49`$UID` is the uid for your process. Using root will lead to logspam.
50
51As mentioned above, these extra audit rules enable `SYSCALL` auditing which
52in turn lets the tool inspect arguments for a pre-selected subset of syscalls.
53The list of syscalls here matches the list of keys in `arg_inspection`.
54
55```shell
56for arch in b32 b64; do
57 auditctl -a exit,always -F uid=$UID -F arch=$arch -S ioctl -S socket \
58 -S prctl -S mmap -S mprotect \
59 $([ "$arch" = "b32" ] && echo "-S mmap2") -c
60done
61touch /tmp/empty.policy
62```
63
64#### Run your program under minijail with an empty policy
65
66Again, this can be done via your upstart conf. Just be sure to stimulate all
67corner cases, error conditions, etc for comprehensive coverage.
68
69```shell
70minijail0 -u $UID -g $GID -L -S /tmp/empty.policy -- <program>
71```
72
73#### Generate policy using the audit.log
74
75```shell
76./tools/generate_seccomp_policy.py --audit-comm $PROGRAM_NAME audit.log \
77 > $PROGRAM_NAME.policy
78```
79
80Note that the tool can also consume multiple audit logs and/or strace traces to
81produce one unified policy.
82
83## compile_seccomp_policy.py
84
85An external seccomp-bpf compiler that is documented [here][3]. This uses a
86slightly different syntax and generates highly-optimized BPF binaries that can
87be provided to `minijail0`'s `--seccomp-bpf-binary` or `libminijail`'s
88`minijail_set_secomp_filters()`. This requires the existence of an
89architecture-specific `constants.json` file that contains the mapping of syscall
90names to numbers, the values of any compile-time constants that could be used to
91simplify the parameter declaration for filters (like `O_RDONLY` and any other
92constant defined in typical headers in `/usr/include`).
93
94Policy files can also include references to frequency files, which enable
95profile-guided optimization of the generated BPF code.
96
97The generated BPF code can be analyzed using
98[libseccomp](https://github.com/seccomp/libseccomp)'s `tools/scmp_bpf_disasm`.
99
100### Sample usage
101
102```shell
103make minijail0 constants.json
104
105# Create the .policy file using the syntax described in the documentation.
106cat > test/seccomp.policy <<EOF
107read: allow
108write: allow
109rt_sigreturn: allow
110exit: allow
111EOF
112
113# Compile the .policy file into a .bpf filter
114./tools/compile_seccomp_policy.py test/seccomp.policy test/seccomp.bpf
115
116# Load the filter to sandbox your program.
117./minijail0 --seccomp-bpf-binary=test/seccomp.bpf -- <program>
118```
119
120## generate_constants_json.py
121
122This script generates the `constants.json` file from LLVM IR assembly files.
123This makes it easier to generate architecture-specific `constants.json` files at
124build-time.
125
126[1]: https://people.redhat.com/sgrubb/audit/
127[2]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/chap-system_auditing
128[3]: https://docs.google.com/document/d/e/2PACX-1vQOeYLWmJJrRWvglnMo5cynkUe0gZ9wVsndLLePkJg6dfUXSOUWoveBBeY3u5nQMlEU4dt_vRgj0ifR/pub
129