Skip to content

Commit 4838ed0

Browse files
committed
[lldb][Docs] Add Guarded Control Stack to AArch64 Linux page
The meat of this is how we execute expressions and deal with the aftermath. For most users this will never be a concern, so it functions more as a design doc than anything else.
1 parent 427be07 commit 4838ed0

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

lldb/docs/use/aarch64-linux.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,54 @@ bytes.
229229

230230
`zt0`'s value and whether it is active or not will be saved prior to
231231
expression evaluation and restored afterwards.
232+
233+
## Guarded Control Stack Extension (GCS)
234+
235+
GCS support includes the following new registers:
236+
237+
* `gcs_features_enabled`
238+
* `gcs_features_locked`
239+
* `gcspr_el0`
240+
241+
These map to the registers ptrace provides. The first two have had a `gcs_`
242+
prefix added as their names are too generic without it.
243+
244+
When the GCS is enabled the kernel allocates a memory region for it. This region
245+
has a special attribute that LLDB will detect and presents like this:
246+
```
247+
(lldb) memory region --all
248+
<...>
249+
[0x0000fffff7a00000-0x0000fffff7e00000) rw-
250+
shadow stack: yes
251+
[0x0000fffff7e00000-0x0000fffff7e10000) ---
252+
```
253+
254+
`shadow stack` is a generic term used in the kernel for secure stack
255+
extensions like GCS.
256+
257+
### Expression Evaluation
258+
259+
To execute an expression, LLDB must push the return address of the expression
260+
wrapper (usually the entry point of the program) to the Guarded Control Stack.
261+
It does this by decrementing `gcspr_el0` and writing to the location that
262+
`gcspr_el0` then points to (instead of using the GCS push instructions).
263+
264+
After an expression finishes, LLDB will restore the contents of all 3 registers,
265+
apart from the enable bit of `gcs_features_enabled`.
266+
267+
This is because there are limits on how often and from where you can set this
268+
value. We cannot enable GCS from ptrace at all and it is expected that a process
269+
that has enabled GCS then disabled it, will not enable it again. The simplest
270+
choice was to not restore the enable bit at all. It's up to the user or
271+
program to manage that value.
272+
273+
The return address that was pushed onto the Guarded Control Stack will be left
274+
in place. As will any values that were pushed to the stack by functions run
275+
during the expresison.
276+
277+
When the process resumes, `gcspr_el0` will be pointing to the original entry
278+
on the stack. So the other values will have no effect and likely be overwritten
279+
by future function calls.
280+
281+
LLDB does not track and restore changes to general memory during expressions,
282+
so not restoring the GCS contents fits with the current behaviour.

0 commit comments

Comments
 (0)