On Thu, Jan 19, 2023 at 01:22:54PM -0800, Rick Edgecombe wrote: > From: Yu-cheng Yu <yu-cheng.yu@xxxxxxxxx> > > The CPU performs "shadow stack accesses" when it expects to encounter > shadow stack mappings. These accesses can be implicit (via CALL/RET > instructions) or explicit (instructions like WRSS). > > Shadow stack accesses to shadow-stack mappings can result in faults in > normal, valid operation just like regular accesses to regular mappings. > Shadow stacks need some of the same features like delayed allocation, swap > and copy-on-write. The kernel needs to use faults to implement those > features. > > The architecture has concepts of both shadow stack reads and shadow stack > writes. Any shadow stack access to non-shadow stack memory will generate > a fault with the shadow stack error code bit set. > > This means that, unlike normal write protection, the fault handler needs > to create a type of memory that can be written to (with instructions that > generate shadow stack writes), even to fulfill a read access. So in the > case of COW memory, the COW needs to take place even with a shadow stack > read. Otherwise the page will be left (shadow stack) writable in > userspace. So to trigger the appropriate behavior, set FAULT_FLAG_WRITE > for shadow stack accesses, even if the access was a shadow stack read. > > For the purpose of making this clearer, consider the following example. > If a process has a shadow stack, and forks, the shadow stack PTEs will > become read-only due to COW. If the CPU in one process performs a shadow > stack read access to the shadow stack, for example executing a RET and > causing the CPU to read the shadow stack copy of the return address, then > in order for the fault to be resolved the PTE will need to be set with > shadow stack permissions. But then the memory would be changeable from > userspace (from CALL, RET, WRSS, etc). So this scenario needs to trigger > COW, otherwise the shared page would be changeable from both processes. > > Shadow stack accesses can also result in errors, such as when a shadow > stack overflows, or if a shadow stack access occurs to a non-shadow-stack > mapping. Also, generate the errors for invalid shadow stack accesses. > > Tested-by: Pengfei Xu <pengfei.xu@xxxxxxxxx> > Tested-by: John Allen <john.allen@xxxxxxx> > Signed-off-by: Yu-cheng Yu <yu-cheng.yu@xxxxxxxxx> Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> -- Kees Cook