Blob


1 Debugging for something unrelated, I noticed that on linux gmid’ server process would crash upon SIGHUP. I never noticed it before because (unfortunately) ‘ulimit -c 0’ seems to be the default on various systems (i.e. no core files) and I started testing on-the-fly reconfiguration only recently.
3 What was particularly strange was that I got not logging whatsoever. I have a compile-time switch for seccomp to raise a catchable SIGSYS to dump the number of the forbidden system call and exit, but in this case my server processes were killed by a SIGSYS without any debugging info.
5 My first theory was that during the process shutdown (server process gracefully shuts down after a SIGHUP) an unwanted syscall was done, maybe after stderr was flushed and closed and thus my signal handler wasn’t able to print info. But it didn’t seemed the case.
7 On OpenBSD I have used in the past ktrace(1) to trace the system calls done by a process, so I searched for something similar for linux. Turns out, strace is quite flexible.
9 I attached strace to the server process:
11 ```
12 -bash-5.1# strace -p 30232
13 strace: Process 30232 attached
14 epoll_pwait(6,
15 ```
17 Good, the server process is waiting on epoll as it should, let’s send it a SIGHUP:
19 ```
20 -bash-5.1# strace -p 30232
21 strace: Process 30232 attached
22 epoll_pwait(6, 0x55724496a0, 32, -1, NULL, 8) = -1 EINTR (Interrupted system call)
23 --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=30251, si_uid=1000} ---
24 write(8, "\1", 1) = 1
25 rt_sigreturn({mask=[]}) = ?
26 +++ killed by SIGSYS +++
27 ```
29 Oh, what do we have here. rt_sigreturn(2)! (the write is libevent handling the signal)
31 After an event handler is called, to restore the program stack linux injects a call to rt_sigreturn. If that syscall gets blocked by a BPF filter, it fails to handle the SIGSYS caused by the filter itself and just crash.
33 But why for SIGHUP it crashes and for the catchable SIGSYS I was using for the debugging it doesn’t? Well, the SIGSYS handler calls directly _exit, so we don’t rearch the sigreturn.
35 This is just a daily remainder of how low-level seccomp is, and how sometimes it just leaves you clueless, but also a nice opportunity to learn how signals are implemented on linux.