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