# Structure Protection

```{contents}
:local:
```

## 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.
