1.. SPDX-License-Identifier: GPL-2.0 2 3:Author: Deepak Gupta <debug@rivosinc.com> 4:Date: 12 January 2024 5 6========================================================= 7Shadow stack to protect function returns on RISC-V Linux 8========================================================= 9 10This document briefly describes the interface provided to userspace by Linux 11to enable shadow stacks for user mode applications on RISC-V. 12 131. Feature Overview 14-------------------- 15 16Memory corruption issues usually result in crashes. However, in the 17hands of a creative adversary, these issues can result in a variety of 18security problems. 19 20Some of those security issues can be code re-use attacks on programs 21where an adversary can use corrupt return addresses present on the 22stack. chaining them together to perform return oriented programming 23(ROP) and thus compromising the control flow integrity (CFI) of the 24program. 25 26Return addresses live on the stack in read-write memory. Therefore 27they are susceptible to corruption, which allows an adversary to 28control the program counter. On RISC-V, the ``zicfiss`` extension 29provides an alternate stack (the "shadow stack") on which return 30addresses can be safely placed in the prologue of the function and 31retrieved in the epilogue. The ``zicfiss`` extension makes the 32following changes: 33 34- PTE encodings for shadow stack virtual memory 35 An earlier reserved encoding in first stage translation i.e. 36 PTE.R=0, PTE.W=1, PTE.X=0 becomes the PTE encoding for shadow stack pages. 37 38- The ``sspush x1/x5`` instruction pushes (stores) ``x1/x5`` to shadow stack. 39 40- The ``sspopchk x1/x5`` instruction pops (loads) from shadow stack and compares 41 with ``x1/x5`` and if not equal, the CPU raises a ``software check exception`` 42 with ``*tval = 3`` 43 44The compiler toolchain ensures that function prologues have ``sspush 45x1/x5`` to save the return address on shadow stack in addition to the 46regular stack. Similarly, function epilogues have ``ld x5, 47offset(x2)`` followed by ``sspopchk x5`` to ensure that a popped value 48from the regular stack matches with the popped value from the shadow 49stack. 50 512. Shadow stack protections and linux memory manager 52----------------------------------------------------- 53 54As mentioned earlier, shadow stacks get new page table encodings that 55have some special properties assigned to them, along with instructions 56that operate on the shadow stacks: 57 58- Regular stores to shadow stack memory raise store access faults. This 59 protects shadow stack memory from stray writes. 60 61- Regular loads from shadow stack memory are allowed. This allows 62 stack trace utilities or backtrace functions to read the true call 63 stack and ensure that it has not been tampered with. 64 65- Only shadow stack instructions can generate shadow stack loads or 66 shadow stack stores. 67 68- Shadow stack loads and stores on read-only memory raise AMO/store 69 page faults. Thus both ``sspush x1/x5`` and ``sspopchk x1/x5`` will 70 raise AMO/store page fault. This simplies COW handling in kernel 71 during fork(). The kernel can convert shadow stack pages into 72 read-only memory (as it does for regular read-write memory). As 73 soon as subsequent ``sspush`` or ``sspopchk`` instructions in 74 userspace are encountered, the kernel can perform COW. 75 76- Shadow stack loads and stores on read-write or read-write-execute 77 memory raise an access fault. This is a fatal condition because 78 shadow stack loads and stores should never be operating on 79 read-write or read-write-execute memory. 80 813. ELF and psABI 82----------------- 83 84The toolchain sets up :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_BCFI` for 85property :c:macro:`GNU_PROPERTY_RISCV_FEATURE_1_AND` in the notes 86section of the object file. 87 884. Linux enabling 89------------------ 90 91User space programs can have multiple shared objects loaded in their 92address space. It's a difficult task to make sure all the 93dependencies have been compiled with shadow stack support. Thus 94it's left to the dynamic loader to enable shadow stacks for the 95program. 96 975. prctl() enabling 98-------------------- 99 100:c:macro:`PR_SET_SHADOW_STACK_STATUS` / :c:macro:`PR_GET_SHADOW_STACK_STATUS` / 101:c:macro:`PR_LOCK_SHADOW_STACK_STATUS` are three prctls added to manage shadow 102stack enabling for tasks. These prctls are architecture-agnostic and return 103-EINVAL if not implemented. 104 105* prctl(PR_SET_SHADOW_STACK_STATUS, unsigned long arg) 106 107If arg = :c:macro:`PR_SHADOW_STACK_ENABLE` and if CPU supports 108``zicfiss`` then the kernel will enable shadow stacks for the task. 109The dynamic loader can issue this :c:macro:`prctl` once it has 110determined that all the objects loaded in address space have support 111for shadow stacks. Additionally, if there is a :c:macro:`dlopen` to 112an object which wasn't compiled with ``zicfiss``, the dynamic loader 113can issue this prctl with arg set to 0 (i.e. 114:c:macro:`PR_SHADOW_STACK_ENABLE` being clear) 115 116* prctl(PR_GET_SHADOW_STACK_STATUS, unsigned long * arg) 117 118Returns the current status of indirect branch tracking. If enabled 119it'll return :c:macro:`PR_SHADOW_STACK_ENABLE`. 120 121* prctl(PR_LOCK_SHADOW_STACK_STATUS, unsigned long arg) 122 123Locks the current status of shadow stack enabling on the 124task. Userspace may want to run with a strict security posture and 125wouldn't want loading of objects without ``zicfiss`` support. In this 126case userspace can use this prctl to disallow disabling of shadow 127stacks on the current task. 128 1295. violations related to returns with shadow stack enabled 130----------------------------------------------------------- 131 132Pertaining to shadow stacks, the CPU raises a ``software check 133exception`` upon executing ``sspopchk x1/x5`` if ``x1/x5`` doesn't 134match the top of shadow stack. If a mismatch happens, then the CPU 135sets ``*tval = 3`` and raises the exception. 136 137The Linux kernel will treat this as a :c:macro:`SIGSEGV` with code = 138:c:macro:`SEGV_CPERR` and follow the normal course of signal delivery. 139 1406. Shadow stack tokens 141----------------------- 142 143Regular stores on shadow stacks are not allowed and thus can't be 144tampered with via arbitrary stray writes. However, one method of 145pivoting / switching to a shadow stack is simply writing to the CSR 146``CSR_SSP``. This will change the active shadow stack for the 147program. Writes to ``CSR_SSP`` in the program should be mostly 148limited to context switches, stack unwinds, or longjmp or similar 149mechanisms (like context switching of Green Threads) in languages like 150Go and Rust. CSR_SSP writes can be problematic because an attacker can 151use memory corruption bugs and leverage context switching routines to 152pivot to any shadow stack. Shadow stack tokens can help mitigate this 153problem by making sure that: 154 155- When software is switching away from a shadow stack, the shadow 156 stack pointer should be saved on the shadow stack itself (this is 157 called the ``shadow stack token``). 158 159- When software is switching to a shadow stack, it should read the 160 ``shadow stack token`` from the shadow stack pointer and verify that 161 the ``shadow stack token`` itself is a pointer to the shadow stack 162 itself. 163 164- Once the token verification is done, software can perform the write 165 to ``CSR_SSP`` to switch shadow stacks. 166 167Here "software" could refer to the user mode task runtime itself, 168managing various contexts as part of a single thread. Or "software" 169could refer to the kernel, when the kernel has to deliver a signal to 170a user task and must save the shadow stack pointer. The kernel can 171perform similar procedure itself by saving a token on the user mode 172task's shadow stack. This way, whenever :c:macro:`sigreturn` happens, 173the kernel can read and verify the token and then switch to the shadow 174stack. Using this mechanism, the kernel helps the user task so that 175any corruption issue in the user task is not exploited by adversaries 176arbitrarily using :c:macro:`sigreturn`. Adversaries will have to make 177sure that there is a valid ``shadow stack token`` in addition to 178invoking :c:macro:`sigreturn`. 179 1807. Signal shadow stack 181----------------------- 182The following structure has been added to sigcontext for RISC-V:: 183 184 struct __sc_riscv_cfi_state { 185 unsigned long ss_ptr; 186 }; 187 188As part of signal delivery, the shadow stack token is saved on the 189current shadow stack itself. The updated pointer is saved away in the 190:c:macro:`ss_ptr` field in :c:macro:`__sc_riscv_cfi_state` under 191:c:macro:`sigcontext`. The existing shadow stack allocation is used 192for signal delivery. During :c:macro:`sigreturn`, kernel will obtain 193:c:macro:`ss_ptr` from :c:macro:`sigcontext`, verify the saved 194token on the shadow stack, and switch the shadow stack. 195