[Lldb-commits] [lldb] [lldb][Docs] Add Guarded Control Stack to AArch64 Linux page (PR #117860)
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Wed Dec 11 05:57:42 PST 2024
https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/117860
>From 4838ed0ef8a62041981e61a8d405251bb32c147d Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 27 Aug 2024 15:22:10 +0100
Subject: [PATCH 1/2] [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.
---
lldb/docs/use/aarch64-linux.md | 51 ++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/lldb/docs/use/aarch64-linux.md b/lldb/docs/use/aarch64-linux.md
index 393838dc0bb4f5..425336ddd81e2f 100644
--- a/lldb/docs/use/aarch64-linux.md
+++ b/lldb/docs/use/aarch64-linux.md
@@ -229,3 +229,54 @@ bytes.
`zt0`'s value and whether it is active or not will be saved prior to
expression evaluation and restored afterwards.
+
+## Guarded Control Stack Extension (GCS)
+
+GCS support includes the following new registers:
+
+* `gcs_features_enabled`
+* `gcs_features_locked`
+* `gcspr_el0`
+
+These map to the registers ptrace provides. The first two have had a `gcs_`
+prefix added as their names are too generic without it.
+
+When the GCS is enabled the kernel allocates a memory region for it. This region
+has a special attribute that LLDB will detect and presents like this:
+```
+ (lldb) memory region --all
+ <...>
+ [0x0000fffff7a00000-0x0000fffff7e00000) rw-
+ shadow stack: yes
+ [0x0000fffff7e00000-0x0000fffff7e10000) ---
+```
+
+`shadow stack` is a generic term used in the kernel for secure stack
+extensions like GCS.
+
+### Expression Evaluation
+
+To execute an expression, LLDB must push the return address of the expression
+wrapper (usually the entry point of the program) to the Guarded Control Stack.
+It does this by decrementing `gcspr_el0` and writing to the location that
+`gcspr_el0` then points to (instead of using the GCS push instructions).
+
+After an expression finishes, LLDB will restore the contents of all 3 registers,
+apart from the enable bit of `gcs_features_enabled`.
+
+This is because there are limits on how often and from where you can set this
+value. We cannot enable GCS from ptrace at all and it is expected that a process
+that has enabled GCS then disabled it, will not enable it again. The simplest
+choice was to not restore the enable bit at all. It's up to the user or
+program to manage that value.
+
+The return address that was pushed onto the Guarded Control Stack will be left
+in place. As will any values that were pushed to the stack by functions run
+during the expresison.
+
+When the process resumes, `gcspr_el0` will be pointing to the original entry
+on the stack. So the other values will have no effect and likely be overwritten
+by future function calls.
+
+LLDB does not track and restore changes to general memory during expressions,
+so not restoring the GCS contents fits with the current behaviour.
>From 4916c3c3aa74eb586d4b70792922fb12d4021dae Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Wed, 11 Dec 2024 13:57:16 +0000
Subject: [PATCH 2/2] Address Omair's comments
---
lldb/docs/use/aarch64-linux.md | 40 +++++++++++++++++++++-------------
1 file changed, 25 insertions(+), 15 deletions(-)
diff --git a/lldb/docs/use/aarch64-linux.md b/lldb/docs/use/aarch64-linux.md
index 425336ddd81e2f..7c6157ce9df2af 100644
--- a/lldb/docs/use/aarch64-linux.md
+++ b/lldb/docs/use/aarch64-linux.md
@@ -256,27 +256,37 @@ extensions like GCS.
### Expression Evaluation
-To execute an expression, LLDB must push the return address of the expression
-wrapper (usually the entry point of the program) to the Guarded Control Stack.
-It does this by decrementing `gcspr_el0` and writing to the location that
-`gcspr_el0` then points to (instead of using the GCS push instructions).
-
-After an expression finishes, LLDB will restore the contents of all 3 registers,
-apart from the enable bit of `gcs_features_enabled`.
-
-This is because there are limits on how often and from where you can set this
-value. We cannot enable GCS from ptrace at all and it is expected that a process
+To execute an expression when GCS is enabled, LLDB must push the return
+address of the expression wrapper (usually the entry point of the program)
+to the Guarded Control Stack. It does this by decrementing `gcspr_el0` and
+writing to the location now pointed to by `gcspr_el0` (instead of using the
+GCS push instructions).
+
+After an expression finishes, LLDB will restore the contents of all 3
+GCS registers, apart from the enable bit of `gcs_features_enabled`. This is
+because there are limits on how often and from where you can set this
+bit.
+
+We cannot enable GCS from ptrace at all and it is expected that a process
that has enabled GCS then disabled it, will not enable it again. The simplest
-choice was to not restore the enable bit at all. It's up to the user or
-program to manage that value.
+choice was to not restore the enable bit at all. It is up to the user or
+program to manage that bit.
-The return address that was pushed onto the Guarded Control Stack will be left
+The return address that LLDB pushed onto the Guarded Control Stack will be left
in place. As will any values that were pushed to the stack by functions run
during the expresison.
When the process resumes, `gcspr_el0` will be pointing to the original entry
-on the stack. So the other values will have no effect and likely be overwritten
-by future function calls.
+on the guarded control stack. So the other values will have no effect and
+likely be overwritten by future function calls.
LLDB does not track and restore changes to general memory during expressions,
so not restoring the GCS contents fits with the current behaviour.
+
+Note that if GCS is disabled and an expression enables it, LLDB will not
+be able to setup the return address and it is up to that expression to do that
+if it wants to return to LLDB correctly.
+
+If it does not do this, the expression will fail and although most process
+state will be restored, GCS will be left enabled. Which means that the program
+is very unlikely to be able to progress.
More information about the lldb-commits
mailing list