22
33** Tier: 3**
44
5- The target enables Pointer Authentication Code (PAC) support in Rust on AArch64
6- ELF based Linux systems using a pauthtest ABI (provided by LLVM) and
7- pauthtest- enabled sysroot with custom musl, serving as a reference libc
8- implementation. It requires dynamic linking with a pauthtest-enabled dynamic
9- linker serving as ELF interpreter capable of resolving pauth relocations and
10- respecting pauthtest ABI constraints.
5+ This target enables Pointer Authentication Code (PAC) support in Rust on AArch64
6+ ELF- based Linux systems. It uses the ` aarch64-unknown-linux- pauthtest` LLVM
7+ target and a pointer-authentication- enabled sysroot with a custom musl as a
8+ reference libc implementation. Dynamic linking is required, with a dynamic
9+ linker acting as the ELF interpreter that can resolve pauth relocations and
10+ enforce pointer authentication constraints.
1111
1212Supported features include:
13- * authenticating signed function pointers for extern "C" function calls
14- (corresponds to ` -fptrauth-calls ` included in pauthtest ABI as defined in
15- LLVM)
16- * signing return address before spilling to stack and authenticating return
17- address after restoring from stack for non-leaf functions (corresponds to
18- ` -fptrauth-returns ` )
19- * trapping if authentication failure is detected and FPAC feature is not present
13+ * authentication of signed function pointers for extern "C" calls (corresponds
14+ to LLVM's ` -fptrauth-calls ` )
15+ * signing of return addresses before spilling to the stack and authentication
16+ after restoring for non-leaf functions (corresponds to ` -fptrauth-returns ` )
17+ * trapping on authentication failure when the FPAC feature is not present
2018 (corresponds to ` -fptrauth-auth-traps ` )
21- * signing of init/fini array entries with the signing schema used for pauthtest
22- ABI (corresponding to ` -fptrauth-init-fini ` ,
19+ * signing of init/fini array entries using the LLVM-defined pointer
20+ authentication scheme (corresponds to ` -fptrauth-init-fini ` and
2321 ` -fptrauth-init-fini-address-discrimination ` )
24- * non-ABI-affecting indirect control flow hardening features included in
25- pauthtest ABI (corresponding to ` -faarch64-jump-table-hardening ` ,
22+ * non-ABI-affecting indirect control- flow hardening features as implemented in
23+ LLVM (corresponds to ` -faarch64-jump-table-hardening ` and
2624 ` -fptrauth-indirect-gotos ` )
2725* signed ELF GOT entries (gated behind ` -Z ptrauth-elf-got ` , off by default)
2826
@@ -35,6 +33,19 @@ Existing compiler support, such as enabling branch authentication instructions
3533return addresses (` pac-ret ` ). The new target goes further by enabling ABI-level
3634pointer authentication support.
3735
36+ This target does not define a new ABI; it builds on the existing C/C++ language
37+ ABI with pointer authentication support added. However, different authentication
38+ features, encoded in the signing schema, are not ABI-compatible with one
39+ another.
40+
41+ Useful links:
42+ * Clang pointer authentication documentation:
43+ https://clang.llvm.org/docs/PointerAuthentication.html
44+ * LLVM pointer authentication documentation:
45+ https://llvm.org/docs/PointerAuth.html
46+ * PAuth ABI Extension to ELF for the AArch64 architecture:
47+ https://github.com/ARM-software/abi-aa/blob/main/pauthabielf64/pauthabielf64.rst
48+
3849## Target maintainers
3950
4051[ @jchlanda ] ( https://github.com/jchlanda )
5263
5364## Building the toolchain
5465
55- Building this target requires a pauthtest- enabled sysroot based on a custom musl
56- toolchain. The sysroot must be available on the system before compilation. To
57- build it, follow the instructions in the [ build scripts
66+ Building this target requires a pointer-authentication- enabled sysroot based on
67+ a custom musl toolchain. The sysroot must be available on the system before
68+ compilation. To build it, follow the instructions in the [ build scripts
5869repo] ( https://github.com/access-softek/pauth-toolchain-build-scripts ) .
5970
6071The target uses Clang, please make sure it is ` v22.1.0 ` or higher. When using a
@@ -85,7 +96,7 @@ a wrapper its name must contain `clang`. A recommended name is
8596` <version> ` with LLVM's version. Make the wrapper executable.
8697
8798To verify that the toolchain layout is correct, check that:
88- * the sysroot contains a pauthtest -enabled version of libunwind
99+ * the sysroot contains a pointer-authentication -enabled version of libunwind
89100 (` <toolchain_root>/aarch64-linux-pauthtest/usr/lib/libunwind.so ` ),
90101* the Clang resource directory contains the appropriate ` compiler-rt ` objects
91102 (` <toolchain_root>/lib/clang/<version>/lib/aarch64-unknown-linux-pauthtest/{clang_rt.crtbegin.o,clang_rt.crtend.o} ` )
@@ -155,16 +166,20 @@ index 0564f2e..a8a0d1a 100644
155166 if cfg!(target_vendor = "apple") {
156167 self.ip()
157168+ } else if cfg!(target_env = "pauthtest") {
158- + // NOTE: As ip here is not signed (raw, non-PAC-enabled pointer) we
159- + // must not use uw::_Unwind_FindEnclosingFunction. This is because,
160- + // for pauthtest toolchain, libunwind will try to authenticate and
161- + // resign it. Signing here (apart from risking creating a signing
162- + // oracle) is not possible. According to the schema the value must
163- + // be signed using SP as the discriminator - which is the problem.
164- + // SP obtained here would not match the SP at the auth-resign time,
165- + // as uw::_Unwind_FindEnclosingFunction creates a new context so
166- + // the SP used for signing here would belong to a different frame
167- + // that the one used for auth-resign. Hence return a raw value.
169+ + // NOTE: ip here is an unsigned (raw) pointer, so we must not use
170+ + // uw::_Unwind_FindEnclosingFunction.
171+ + //
172+ + // Otherwise, in the pointer-authentication-enabled reference
173+ + // toolchain, libunwind would attempt to authenticate and re-sign
174+ + // values. Performing signing here is not safe: it could create a
175+ + // signing oracle, and more importantly it is incorrect under the
176+ + // expected signing schema.
177+ + // The schema requires the stack pointer (SP) as the discriminator.
178+ + // However, the SP available at this point would not match the SP
179+ + // at authentication/re-sign time, since
180+ + // _Unwind_FindEnclosingFunction constructs a new unwind context.
181+ + // The SP used here would therefore correspond to a different frame.
182+ + // As a result, we must return the raw value.
168183+ self.ip()
169184 } else {
170185 unsafe { uw::_Unwind_FindEnclosingFunction(self.ip()) }
@@ -343,12 +358,13 @@ fails.
343358
344359## Cross-compilation toolchains and C code
345360
346- This target supports interoperability with C code. Use the pauthtest-enabled
347- sysroot, described in building the toolchain section of this document. C code
348- must be compiled with the pauthtest aware compiler. Mixed Rust/C programs are
349- supported and tested (e.g. quicksort examples). Pointer authentication semantics
350- must be consistent across Rust and C components. The target only supports
351- dynamic linking.
361+ This target supports interoperability with C code. A
362+ pointer-authentication-enabled sysroot, built as described in the toolchain
363+ build section of this document, is required. C code must be compiled with a
364+ compiler configuration that supports pointer authentication. Mixed Rust/C
365+ programs are supported and tested (e.g. quicksort examples). Pointer
366+ authentication semantics must be consistent across Rust and C components. Only
367+ dynamic linking is supported.
352368
353369The target can be cross-compiled from any Linux-based host, but execution
354370requires an AArch64 system that implements Pointer Authentication (PAC). In
@@ -375,7 +391,7 @@ The following categories are supported (all present in tree):
375391* End-to-end execution tests
376392 * Rust-driven quicksort (pauth-quicksort-rust-driver)
377393 * C-driven quicksort (pauth-quicksort-c-driver)
378- * UI error reporting (pauthtest does not support ` +crt-static ` )
394+ * UI error reporting (the target does not support ` +crt-static ` )
379395 * crt-static-pauthtest.rs
380396
381397All tests from ` assembly-llvm ` , ` codegen-llvm ` , ` codegen-units ` , ` coverage ` ,
@@ -412,7 +428,10 @@ For more information please see the discussion in the [rust-lang issue
412428tracker] ( https://github.com/rust-lang/rust/issues/152532 ) .
413429
414430The current version only supports C interoperability with pointer authentication
415- features explicitly mentioned at the beginning of this document.
431+ features explicitly mentioned at the beginning of this document. Further work is
432+ needed to support configurable signing schemas (i.e. selection of signing keys,
433+ discriminators, address diversity, and features opt-in/opt-out) as defined by
434+ the LLVM pointer authentication model.
416435
417436C++ interoperability is not currently supported. Features such as signing C++
418437member function pointers, virtual function pointers, and virtual table pointers
0 commit comments