Re: [PATCH 00/35] Shadow stacks for userspace
From: "Andy Lutomirski" <luto@kernel.org>
Date: 2022-02-28 20:31:12
Also in:
linux-arch, linux-doc, linux-mm, lkml
On Mon, Feb 28, 2022, at 12:27 PM, Mike Rapoport wrote:
On Wed, Feb 09, 2022 at 06:37:53PM -0800, Andy Lutomirski wrote:quoted
On 2/8/22 18:18, Edgecombe, Rick P wrote:quoted
On Tue, 2022-02-08 at 20:02 +0300, Cyrill Gorcunov wrote: Still wrapping my head around the CRIU save and restore steps, but another general approach might be to give ptrace the ability to temporarily pause/resume/set CET enablement and SSP for a stopped thread. Then injected code doesn't need to jump through any hoops or possibly run into road blocks. I'm not sure how much this opens things up if the thread has to be stopped...Hmm, that's maybe not insane. An alternative would be to add a bona fide ptrace call-a-function mechanism. I can think of two potentially usable variants: 1. Straight call. PTRACE_CALL_FUNCTION(addr) just emulates CALL addr, shadow stack push and all. 2. Signal-style. PTRACE_CALL_FUNCTION_SIGFRAME injects an actual signal frame just like a real signal is being delivered with the specified handler. There could be a variant to opt-in to also using a specified altstack and altshadowstack.Using ptrace() will not solve CRIU's issue with sigreturn because sigreturn is called from the victim context rather than from the criu process that controls the dump and uses ptrace().
I'm not sure I follow.
Even with the current shadow stack interface Rick proposed, CRIU can restore the victim using ptrace without any additional knobs, but we loose an important ability to "self-cure" the victim from the parasite in case anything goes wrong with criu control process. Moreover, the issue with backward compatibility is not with ptrace but with sigreturn and it seems that criu is not its only user.
So we need an ability for a tracer to cause the tracee to call a function and to return successfully. Apparently a gdb branch can already do this with shstk, and my PTRACE_CALL_FUNCTION_SIGFRAME should also do the trick. I don't see why we need a sigretur-but-dont-verify -- we just need this mechanism to create a frame such that sigreturn actually works. --Andy