• Rick Edgecombe's avatar
    x86/mm: Check shadow stack page fault errors · fd5439e0
    Rick Edgecombe authored
    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.
    Co-developed-by: default avatarYu-cheng Yu <yu-cheng.yu@intel.com>
    Signed-off-by: default avatarYu-cheng Yu <yu-cheng.yu@intel.com>
    Signed-off-by: default avatarRick Edgecombe <rick.p.edgecombe@intel.com>
    Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
    Reviewed-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
    Reviewed-by: default avatarKees Cook <keescook@chromium.org>
    Acked-by: default avatarMike Rapoport (IBM) <rppt@kernel.org>
    Tested-by: default avatarPengfei Xu <pengfei.xu@intel.com>
    Tested-by: default avatarJohn Allen <john.allen@amd.com>
    Tested-by: default avatarKees Cook <keescook@chromium.org>
    Link: https://lore.kernel.org/all/20230613001108.3040476-16-rick.p.edgecombe%40intel.com
    fd5439e0
trap_pf.h 780 Bytes