On 2024-08-01 13:06, Mark Brown wrote: > The arm64 Guarded Control Stack (GCS) feature provides support for > hardware protected stacks of return addresses, intended to provide > hardening against return oriented programming (ROP) attacks and to make > it easier to gather call stacks for applications such as profiling. > > When GCS is active a secondary stack called the Guarded Control Stack is > maintained, protected with a memory attribute which means that it can > only be written with specific GCS operations. The current GCS pointer > can not be directly written to by userspace. When a BL is executed the > value stored in LR is also pushed onto the GCS, and when a RET is > executed the top of the GCS is popped and compared to LR with a fault > being raised if the values do not match. GCS operations may only be > performed on GCS pages, a data abort is generated if they are not. > > The combination of hardware enforcement and lack of extra instructions > in the function entry and exit paths should result in something which > has less overhead and is more difficult to attack than a purely software > implementation like clang's shadow stacks. > > This series implements support for use of GCS by userspace, along with > support for use of GCS within KVM guests. It does not enable use of GCS > by either EL1 or EL2, this will be implemented separately. Executables > are started without GCS and must use a prctl() to enable it, it is > expected that this will be done very early in application execution by > the dynamic linker or other startup code. For dynamic linking this will > be done by checking that everything in the executable is marked as GCS > compatible. > > x86 has an equivalent feature called shadow stacks, this series depends > on the x86 patches for generic memory management support for the new > guarded/shadow stack page type and shares APIs as much as possible. As > there has been extensive discussion with the wider community around the > ABI for shadow stacks I have as far as practical kept implementation > decisions close to those for x86, anticipating that review would lead to > similar conclusions in the absence of strong reasoning for divergence. > > The main divergence I am concious of is that x86 allows shadow stack to > be enabled and disabled repeatedly, freeing the shadow stack for the > thread whenever disabled, while this implementation keeps the GCS > allocated after disable but refuses to reenable it. This is to avoid > races with things actively walking the GCS during a disable, we do > anticipate that some systems will wish to disable GCS at runtime but are > not aware of any demand for subsequently reenabling it. > > x86 uses an arch_prctl() to manage enable and disable, since only x86 > and S/390 use arch_prctl() a generic prctl() was proposed[1] as part of a > patch set for the equivalent RISC-V Zicfiss feature which I initially > adopted fairly directly but following review feedback has been revised > quite a bit. > > We currently maintain the x86 pattern of implicitly allocating a shadow > stack for threads started with shadow stack enabled, there has been some > discussion of removing this support and requiring the use of clone3() > with explicit allocation of shadow stacks instead. I have no strong > feelings either way, implicit allocation is not really consistent with > anything else we do and creates the potential for errors around thread > exit but on the other hand it is existing ABI on x86 and minimises the > changes needed in userspace code. > > glibc and bionic changes using this ABI have been implemented and > tested. Headless Android systems have been validated and Ross Burton > has used this code has been used to bring up a Yocto system with GCS > enabed as standard, a test implementation of V8 support has also been > done. > > There is an open issue with support for CRIU, on x86 this required the > ability to set the GCS mode via ptrace. This series supports > configuring mode bits other than enable/disable via ptrace but it needs > to be confirmed if this is sufficient. > > The series depends on support for shadow stacks in clone3(), that series > includes the addition of ARCH_HAS_USER_SHADOW_STACK. > > https://lore.kernel.org/r/20240731-clone3-shadow-stack-v7-0-a9532eebfb1d@xxxxxxxxxx > Verified this patchset on a FVP. Tested-by: Linux Kernel Functional Testing <lkft@xxxxxxxxxx> Cheers, Anders