RE: [EXTERNAL] Re: signal/signal_deliver and bpf_send_signal()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> -----Original Message-----
> From: Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx>
> Sent: 14 August 2021 00:08
> To: Yonghong Song <yhs@xxxxxx>
> Cc: Kevin Sheldrake <Kevin.Sheldrake@xxxxxxxxxxxxx>; bpf
> <bpf@xxxxxxxxxxxxxxx>
> Subject: [EXTERNAL] Re: signal/signal_deliver and bpf_send_signal()
> 
> 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?

Thanks both for your responses.  Regarding this one, if I send SIGHUP or
SIGTERM then it arrives before the SIGSEGV, so I don't believe it is a case
Of SIGSEGV winning the race.  I'm therefore going to assume the special
processing is needed and missing.  Thanks for looking into this though.

> 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?

This is a clever idea but I'm targeting kernels pre 5.5 where fentry etc
were introduced.  If I can shift the requirements to >=5.5 then I'll
go down this route and report back.  Thanks for the idea.

Kev

--
Kevin Sheldrake
Microsoft Threat Intelligence Centre





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux