[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CABV8kRzzs5ktyJTrs+m1uY3QY1v+XS5NrOUB+H4CuhfRS_vvdw@mail.gmail.com>
Date: Sat, 11 Apr 2020 03:13:40 -0400
From: Keno Fischer <keno@...iacomputing.com>
To: Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Cc: Jamie Iles <jamie.iles@...cle.com>,
Oleg Nesterov <oleg@...hat.com>,
Andrew Morton <akpm@...ux-foundation.org>
Subject: ptrace and SIGNAL_UNKILLABLE
Hi folks,
I was seeing some unexpected hangs when ptracing
a buggy container init, that I didn't see when just running
it regularly. Some investigation pointed me to commit
[eb61b5911] signal: don't remove SIGNAL_UNKILLABLE for traced tasks
In particular, consider a container init that just segfaults:
segv.c:
int main(void) {
return *((int*)-1);
}
$ gcc -o segv segv.c
unshare -p -U -r -f ./segv
Segmentation fault
$ strace -f unshare -p -U -r -f ./segv
[hangs]
The reason this hangs is that above commit prevents ptrace'd
tasks from having their SIGNAL_UNKILLABLE flag removed,
so when the SIGSEGV gets generated, that flag does not get
unset. When strace re-injects the SIGSEGV, it simply gets
ignored, the process re-enters user space and the whole
ordeal starts over.
I considered sending a patch that updates that code-path
to only preserve SIGNAL_UNKILLABLE for SIGTRAP
signals, but I figured that may yet be insufficient as well.
I think a proper solution would probably refactor the signal
code to allow the call side to decide whether or not to clear
this flag (such that ptrace could elect not to, but otherwise
the process is undisturbed), but I'm not familiar enough with
the code to attempt a patch for that.
If this is what's supposed to happen, or it is infeasible to
correct it, it would be useful to have a ptrace option that
can be set, to nevertheless make the injected signal final.
At the moment, I can't think of a good way to inject such a
signal.
Thanks,
Keno
Powered by blists - more mailing lists