| # Structure Protection | |
| ## Introduction | |
| Structure protection is an *experimental* mitigation | |
| against use-after-free vulnerabilities. For | |
| more information, please see the original [RFC](https://discourse.llvm.org/t/rfc-structure-protection-a-family-of-uaf-mitigation-techniques/85555). | |
| An independent set of documentation will be contributed when the feature | |
| is promoted to stable. | |
| ## Usage | |
| To use structure protection, build your program using one or more of these flags: | |
| - `-fexperimental-allow-pointer-field-protection-attr`: Makes the | |
| `[[clang::pointer_field_protection]]` attribute described below | |
| available for use in code. Without this flag, use of the attribute will | |
| cause an error. This flag acts as a guard against use of the feature | |
| before it is stabilized. When the feature is stabilized, the intent | |
| is that this flag will become a no-op and the attribute will always | |
| be available. | |
| - `-fexperimental-pointer-field-protection-abi`: Enable pointer | |
| field protection on all types that are not considered standard-layout | |
| according to the C++ rules for standard layout. Because this | |
| flag changes the C++ ABI, we refer to this as the pointer | |
| field protection ABI. Specifying this flag also defines the | |
| predefined macro `__POINTER_FIELD_PROTECTION_ABI__`. Implies | |
| `-fexperimental-allow-pointer-field-protection-attr`. | |
| - `-fexperimental-pointer-field-protection-tagged`: On architectures | |
| that support it (currently only AArch64), for types that are not | |
| considered trivially copyable, use the address of the object to compute | |
| the pointer encoding. Specifying this flag also defines the predefined | |
| macro `__POINTER_FIELD_PROTECTION_TAGGED__`. | |
| It is also possible to specify the attribute | |
| `[[clang::pointer_field_protection]]` on a struct type to opt the | |
| struct's pointer fields into pointer field protection, even if the type is | |
| standard layout or none of the command line flags are specified. Note that | |
| this means that the type will not comply with pointer interconvertibility | |
| and other standard layout rules. | |
| Pointer field protection is inherited from bases and non-static data | |
| members. | |
| In order to avoid ABI breakage, the entire C++ part | |
| of the program must be built with a consistent set of | |
| `-fexperimental-pointer-field-protection*` flags, and the C++ standard | |
| library must also be built with the same flags and statically linked | |
| into the program. | |
| To build libc++ with pointer field protection support, pass the following | |
| CMake flags: | |
| ```console | |
| "-DRUNTIMES_${triple}_LIBCXXABI_ENABLE_SHARED=OFF" \ | |
| "-DRUNTIMES_${triple}_LIBCXX_USE_COMPILER_RT=ON" \ | |
| "-DRUNTIMES_${triple}_LIBCXX_PFP=untagged" \ | |
| "-DRUNTIMES_${triple}_LIBCXX_ENABLE_SHARED=OFF" \ | |
| "-DRUNTIMES_${triple}_LIBCXX_TEST_CONFIG=llvm-libc++-static.cfg.in" \ | |
| "-DRUNTIMES_${triple}_LIBUNWIND_ENABLE_SHARED=OFF" \ | |
| ``` | |
| where `${triple}` is your target triple, such as | |
| `aarch64-unknown-linux`. | |
| The resulting toolchain may then be used to build programs | |
| with pointer field protection by passing `-stdlib=libc++ | |
| -fexperimental-pointer-field-protection-abi` at compile time | |
| and `-Wl,-Bstatic -lc++ -lc++abi -Wl,-Bdynamic -lm -fuse-ld=lld | |
| -static-libstdc++` at link time. | |
| ## Implementation | |
| TODO: Document everything else. | |
| The implementation uses deactivation symbols as a mechanism for | |
| globally disabling pointer field protection for a particular field. For | |
| more information, see the [deactivation symbol section of the LangRef](https://llvm.org/docs/LangRef.html#deactivation-symbol-operand-bundles). | |
| These symbols are named as follows: | |
| `__pfp_ds_` followed by the ABI encoding of the type's RTTI object | |
| symbol name followed by `.` followed by the name of the field. |