Skip to content

Commit 6d0dd3d

Browse files
[lldb][Docs] Add Guarded Control Stack to AArch64 Linux page (#117860)
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 304a990 commit 6d0dd3d

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

lldb/docs/use/aarch64-linux.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,64 @@ 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 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 when GCS is enabled, LLDB must push the return
260+
address of the expression wrapper (usually the entry point of the program)
261+
to the Guarded Control Stack. It does this by decrementing `gcspr_el0` and
262+
writing to the location now pointed to by `gcspr_el0` (instead of using the
263+
GCS push instructions).
264+
265+
After an expression finishes, LLDB will restore the contents of all 3
266+
GCS registers, apart from the enable bit of `gcs_features_enabled`. This is
267+
because there are limits on how often and from where you can set this
268+
bit.
269+
270+
GCS cannot be enabled from ptrace and it is expected that a process which
271+
has enabled and then disabled GCS, will not enable it again. The simplest
272+
choice was to not restore the enable bit at all. It is up to the user or
273+
program to manage that bit.
274+
275+
The return address that LLDB pushed onto the Guarded Control Stack will be left
276+
in place. As will any values that were pushed to the stack by functions run
277+
during the expression.
278+
279+
When the process resumes, `gcspr_el0` will be pointing to the original entry
280+
on the guarded control stack. So the other values will have no effect and
281+
likely be overwritten by future function calls.
282+
283+
LLDB does not track and restore changes to general memory during expressions,
284+
so not restoring the GCS contents fits with the current behaviour.
285+
286+
Note that if GCS is disabled and an expression enables it, LLDB will not
287+
be able to setup the return address and it is up to that expression to do that
288+
if it wants to return to LLDB correctly.
289+
290+
If it does not do this, the expression will fail and although most process
291+
state will be restored, GCS will be left enabled. Which means that the program
292+
is very unlikely to be able to progress.

0 commit comments

Comments
 (0)