xref: /linux/Documentation/arch/riscv/zicfiss.rst (revision d30c1683aaecb93d2ab95685dc4300a33d3cea7a)
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