sandboxing: add section on finding failing syscalls
I suspect this is a very common problem to have, so putting it in its
own section should make it easier to find, compared to being mixed in to
the variety of troubleshooting tips. I've also made some of the steps a
bit more explicit, thanks to help from dverkamp@.
BUG=none
TEST=check gitiles rendering
Change-Id: Ib2d3fd09a3b8c09ed12f27b8ae8178617affaf1a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/docs/+/3379763
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Commit-Queue: Harry Cutts <hcutts@chromium.org>
Tested-by: Harry Cutts <hcutts@chromium.org>
diff --git a/sandboxing.md b/sandboxing.md
index 2165dd9..a0195f7 100644
--- a/sandboxing.md
+++ b/sandboxing.md
@@ -451,26 +451,6 @@
* Normally, it's just easier to use the `-n` flag (`no_new_privs`),
which prevents the sandboxed process from obtaining new privileges and
is therefore a good addition for sandboxing.
-* To find a failing syscall without having seccomp logs available (i.e., when
- minijail0 was run without the `-L` option):
- * `dmesg | grep "syscall="` to find something similar to:
-
-```
-NOTICE kernel: [ 586.706239] audit: type=1326 audit(1484586246.124:6): ... comm="<executable>" exe="/path/to/executable" sig=31 syscall=130 compat=0 ip=0x7f4f214881d6 code=0x0
-```
-
-* Then do:
- * `minijail0 -H | grep <nr>`, where `<nr>` is the `syscall=` number
- above, to find the name of the failing syscall.
- * NB: You need to run `minijail0` on the same system as your program as
- the system call tables might be different from the SDK (e.g. x86 is not
- the same as arm).
- * If you do not want to allow an entire syscall, you can only allow
- certain parameters, e.g. `ioctl: arg1 == FDGETPRM`. When the program
- crashes due to a seccomp filter failure, you can use the minidump to
- find the arguments to allow using the [syscall calling conventions].
- * For an online list of syscalls, check out our [syscalls table].
-
* Sometimes Minijail will fail to compile the seccomp filter with an error
similar to:
@@ -494,6 +474,53 @@
should be on the lookout for such failures and the seccomp policies should
be adjusted accordingly.
+#### Finding failing syscalls
+
+If a process violates its seccomp policy, it'll be terminated with `SIGSYS` (Bad
+system call) and you'll see a message like this in `/var/log/messages`:
+
+```
+WARNING minijail0[1415]: libminijail[1415]: child process 1417 had a policy violation (/usr/share/policy/foo.policy)
+```
+
+There are a couple of ways to find out what syscall caused the violation:
+
+* **If you can deploy a debug build of Minijail** (the
+ `chromeos-base/minijail` package built with `USE="cros-debug"`) to the
+ device, and add `-L` to the Minijail command, information on failing
+ syscalls will be logged to `/var/log/audit/audit.log`. (Kernel version 4.14
+ or above is required for this to work.) Note that `-L` also stops policy
+ violations from crashing the process, so execution will succeed.
+
+ A lot of other things are logged to audit.log, so to locate the messages
+ related to your binary, look for messages starting `type=SECCOMP`. For
+ example, here's a violation message caused by the `true` command making
+ syscall 157:
+
+ ```
+ type=SECCOMP msg=audit(1641860367.246:224): auid=0 uid=0 gid=0 ses=2 subj=u:r:minijail:s0 pid=13686 comm="true" exe="/usr/bin/coreutils" sig=0 arch=c000003e syscall=157 compat=0 ip=0x7a28525bde35 code=0x7ffc0000
+ ```
+
+ (Note that longer command names may be truncated in the `comm=` field.)
+
+* **If you have a core dump or minidump** (such as the `.core` file found in
+ `/var/spool/crash/`, or the minidump attached to a crash report), you can
+ open it in a debugger and dump the register values (e.g. with `info
+ registers` in gdb or `register read` in lldb). Check the [syscall calling
+ conventions] for your architecture to determine which registers contain the
+ syscall number and arguments. (Note: 64-bit ARM systems (arm64, aarch64) run
+ userspace programs in 32-bit mode, so you'll want to follow the arm calling
+ conventions in that case.)
+
+Once you have the syscall number, find out the name of the syscall by looking it
+up our in online [syscalls table] or in `minijail0 -H` (run on the same
+architecture as the program you're debugging). You can then add the syscall to
+your policy.
+
+If you do not want to allow an entire syscall, you can only allow certain
+parameters, e.g. `ioctl: arg1 == FDGETPRM`. You can find the values of these
+parameters from a core or minidump using a debugger, as described above.
+
### Installing and applying the generated policy
The policy file needs to be installed in the system, so we need to add it to