On Fri, Aug 13, 2021 at 10:20 AM Yonghong Song <yhs@xxxxxx> wrote: > > > > On 8/13/21 2:57 AM, Kevin Sheldrake wrote: > > Hello > > > > I have a requirement to catch a specific signal hitting a specific process and to send it a SIGSTOP before that signal arrives. This is so that the process can then be attached with ptrace(), but without the necessity of ptrace()ing the process continuously beforehand (due to performance and stability reasons). I thought this might be possible with an eBPF program attached to a tracepoint. > > > > I attached a program to the signal/signal_deliver tracepoint and used bpf_send_signal() to send the SIGSTOP but it didn't stop the process. If I sent SIGTERM or SIGHUP instead it worked as expected, just not SIGSTOP or SIGTSTP. > > > > Sending a SIGSTOP prior to another signal (eg SIGSEGV) works from userland - the process stops and the other signal is queued. > > > > I'm guessing that the reason is that bpf_send_signal() adds the (non-state transitioning) signal to the process signal queue, ignoring SIGSTOP, SIGTSTP, SIGKILL, SIGCONT, but doesn't change the state of processes. Can anyone confirm if that is correct or if there's another possible reason that bpf_send_signal seems to fail to send a SIGSTOP? If so, is this documented anywhere? Is there another way to do this with eBPF? > > Kernel has SIG_KERNEL_IGNORE_MASK like below > > #define SIG_KERNEL_IGNORE_MASK (\ > rt_sigmask(SIGCONT) | rt_sigmask(SIGCHLD) | \ > rt_sigmask(SIGWINCH) | rt_sigmask(SIGURG) ) > > So SIGCONT will be ignored for bpf_send_signal() helper. > > For other signals e.g., SIGSTOP/SIGKILL, there are some comments saying > special processing might be needed. But I think they may still get > delivered. If you use signal/signal_deliver when SIGSEGV is delivered, > is it already too late to do bpf_send_signal() SIGSTOP since that > will be processed after SIGSEGV? Note that SIGSEGV is already delivered? > Too lazy to read the code to know if this will work, but I'll ask anyway. Would it work to do fmod_ret BPF prog right on the entry point in the kernel where the signal is just starting to be processed, and ignoring SIGSEGV completely? Then doing send_signal(SIGSTOP), and then again for SIGSEGV? So, intercept and cancel original signal, inject SIGSTOP, re-introduce original signal? > > > > Many thanks > > > > Kev > > > > -- > > Kevin Sheldrake > > Microsoft Threat Intelligence Centre > >