SIGILL and uretprobes, WAS: [PATCH] uprobes: Free utask on dup_return_instance() failure
From: Andrii Nakryiko
Date: Tue Aug 25 2026 - 14:26:07 EST
On Tue, Aug 25, 2026 at 9:38 AM Andrii Nakryiko
<andrii.nakryiko@xxxxxxxxx> wrote:
>
> On Tue, Aug 25, 2026 at 5:27 AM Oleg Nesterov <oleg@xxxxxxxxxx> wrote:
> >
> > On 08/24, Andrii Nakryiko wrote:
> > >
> > > On Mon, Aug 24, 2026 at 8:57 AM Oleg Nesterov <oleg@xxxxxxxxxx> wrote:
> > > >
> > > > force_exit_sig(SIGILL) can't be ignored too. But I am fine either way.
> > >
> > > Current SIGILL sending is already pretty bad behavior that bites us
> > > periodically, instead of doubling down on killing the user space
> > > process because something about installing uprobe goes wrong, let's
> > > think about a bit less destructive way to do this. Mark uprobe for a
> > > particular process as defunct or "detaching it", or something along
> > > those lines. But not just kill innocent processes.
> >
> > Well. Yes, SIGILL sending acts as BUG_ON(), this is not nice and
>
> The problem is that this is actually not a bug but a very real and
> expected behavior with user-space using fibers or coroutines. Any
> suggestions how we can make this less violent, as it's actually quite
> dangerous and kills production applications when someone (unknowingly)
> tries to uretprobe trace them...
>
IIUC, this SIGILL and coroutines/fibers issue is due to
uprobe_handle_trampoline not finding utrask->return_instances, because
a bit earlier we threw out pending uretprobes due to
arch_uretprobe_is_alive() returned false due to that `regs->sp <=
ret->stack` check (for x86-64).
So the question I hope you can help reason about is a) should we just
ignore utask->return_instances == NULL case and count it as uretprobe
miss and b) should we flip it around, and just not add a new pending
uretprobe if current stack doesn't satisfy this invariant.
In practice this would mean that with fibers we'll get some uretprobes
matched, others dropped, but at least this will be discoverable due to
misses and it won't be killing innocent applications.
And at any rate, we have a per-process limit on number of pending
uretprobes, so there is no risk of having unbounded amount of memory
taken by erratically behaving application breaking uretprobes.
WDYT?
> > probably we can improve the current code. And, just in case, as for
> > uprobe_copy_process() in particular I agree that Option B (make fork()
> > fail) is better.
> >
> > But what, say, uprobe_handle_trampoline() can do if ->return_instances
> > is NULL? Either we have a kernel bug, or the probed task does something
> > wrong. In both cases it is better to kill the task with pr_warn() and
> > generate the core dump.
>
> I don't remember all the code paths, but just shooting in the dark
> there, we can always poison a pointer to distinguish or something? or
> just assume kernel bugs do not happen and ignore NULL. Or something
> along those lines.
>
> >
> > Oleg.
> >