Thread (9 messages) flat view 9 messages, 4 authors, 6d ago

Re: Shadow Stack Locking Semantics between arch's

From: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
Date: 2026-08-27 22:38:03
Also in: linux-arm-kernel, linux-hardening, linux-riscv, lkml

On Thu, 2026-08-27 at 22:41 +0100, Mark Brown wrote:
On Thu, Aug 27, 2026 at 09:27:06PM +0000, Edgecombe, Rick P wrote:
quoted
On Thu, 2026-08-27 at 19:14 +0100, Mark Brown wrote:
quoted
On Thu, Aug 27, 2026 at 12:52:28PM -0500, Bill Roberts wrote:
quoted
quoted
quoted
I am proposing and have questions over the following:
1. What should the behavior be if you had write locked and disable the
shadow stack?
  - I can argue both ways here, -EPERM or success. I think I and most arches
lead to failure.
quoted
quoted
Given that RISC-V doesn't support control of writes it's moot there
at the minute, and x86 currently uses arch_prctl() so will need an
additional API, it seems the path of least resistance is to allow it.
This also avoids locking writes (or pushes, for arm64) on effectively
also locking enable which seems neater.
quoted
Hmm. I can't think of a reason to lock writes and not lock shadow stack too.
Given likely no one is doing this, I wonder if we could change x86's behavior to
match the others?
quoted
The API would makes more sense to prevent disabling shadow stack if writes were
enabled. It could return an EINVAL regardless if it is locked or not? Is that
the arm behavior (forgetting about locked)?
arm64 currently treats each bit independently for simplicity.  The main
use case I see for actually doing that is for preventing enabling writes
or pushes, though in practice I'd expect something doing locks to just
fully lock everything after having enabled the shadow stack.
Locking writes as off makes sense to me. But locking writes on, while leaving
shadow stack unlocked. I'm not sure why you would do that. I thought that was
Bill's scenario.

  We can compose
the features easily enough so it seemed most straightforward to just let
userspace decide what it wants, it keeps the implementation simpler.
quoted
quoted
It has been on my list to look at this
repitition at some point, it had been held up by the clone3() stuff but
that seems to have died a death for now.
quoted
Oh? What was the blocker?
Basically the glibc people weren't convinced they'd ever want to reuse a
shadow stack at which point having the kernel free and reallocate each time
is just as easy.  It saves having to handle corner cases with threads that
didn't exit cleanly.
I thought it was also because they wanted finer grained control of stack sizes
too? But yea, if no libc wants it, it's a hard sell.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help