On Tue, Nov 14, 2023 at 11:11:58PM +0000, Edgecombe, Rick P wrote:
On Tue, 2023-11-14 at 20:05 +0000, Mark Brown wrote:
+ shadow_stack = syscall(__NR_map_shadow_stack, 0, getpagesize(), 0);
Hmm, x86 fails this call if user shadow stack is not supported in the HW or the kernel, but doesn't care if it is enabled on the thread or not. If shadow stack is not enabled (or not yet enabled), shadow stacks are allowed to be mapped. Should it fail if shadow stack is not yet enabled?
Since shadow stack is per thread, map_shadow_stack could still be called on another thread that has it enabled. Basically I don't think blocking it will reduce the possible states the kernel has to handle.
Indeed - I would expect map_shadow_stack() to always succeed if the system supports it since it could reasonably be called as part of the preparation for enabling it and even if someone calls it and never actually uses the resulting memory there's no more harm to that than any other memory allocation. The arm64 code wasn't explicitly caring if we actually had GCS enabled when we clone and just alloacating the stack if requested which on reflection is more just an opportunity for users to mess up than something we usefully want to support.
The traditional way to check if shadow stack is enabled on x86 is the check for a non zero return from the _get_ssp() intrinsic: https://gcc.gnu.org/onlinedocs/gcc-9.2.0/gcc/x86-control-flow-protection-int...
It seems like there will be a need for some generic method of checking if shadow stack is enabled. Maybe a more generic compiler intrinsic/builtin or glibc API (something unrelated to SSP)?
Some sort of feature check in libc would be nice, yes. That said since we really want the tests to run on systems without libc support for the feature (if only as a bootstrapping thing) we'll need to open code anyway. I'll add code to startup which ensures the feature is enabled, we can't rely on it for detection without pain though since it's possible that we might have features locked by the startup code.