Home Explore Blog CI



nixpkgs

32th chunk of `doc/stdenv/stdenv.chapter.md`
e7f735ae6b450018dca6f8e26a2d1542add86b55297d71240000000100000c02
#### `shadowstack` {#shadowstack}

Adds the `-fcf-protection=return` compiler option. This enables the Shadow Stack feature supported by some newer processors, which maintains a user-inaccessible copy of the program's stack containing only return-addresses. When returning from a function, the processor compares the return-address value on the two stacks and throws an error if they do not match, considering it a sign of corruption and possible tampering. This should significantly increase the difficulty of ROP attacks.

For the Shadow Stack to be enabled at runtime, all code linked into a process must be built with Shadow Stack enabled, so this is probably only useful to enable on a wide scale, so that all of a packages dependencies also have the feature enabled.

This is currently only supported on some newer Intel and AMD processors as part of the Intel CET set of features. However, the generated code should continue to work on older processors which will simply omit any of this checking.

This breaks some code that does advanced stack management or exception handling. If enabling this hardening flag it is important to test the result on a system that has known working and enabled CET support, so that any such breakage can be discovered.

#### `trivialautovarinit` {#trivialautovarinit}

Adds the `-ftrivial-auto-var-init=pattern` compiler option. Uninitialized variables generally take on their values based on fragments of previous program state, and attackers can carefully manipulate that state to craft malicious initial values for these variables. This flag causes "trivially-initializable" uninitialized stack variables to be forcibly initialized with a nonzero value that is likely to cause a crash (and therefore be noticed).

Use of this flag is controversial as it can prevent tools that detect uninitialized variable use (such as valgrind) from operating correctly.

This should be turned off or fixed for build errors such as:

```
sorry, unimplemented: __builtin_clear_padding not supported for variable length aggregates
```

#### `pacret` {#pacret}

This flag adds the `-mbranch-protection=pac-ret` compiler option on aarch64-linux targets. This uses ARM v8.3's Pointer Authentication feature to sign function return pointers before adding them to the stack. The pointer's authenticity is then validated before returning to its destination. This dramatically increases the difficulty of ROP exploitation techniques.

This may cause problems with code that does advanced stack manipulation, and debugging/stack-unwinding tools need to be pac-ret aware to work correctly when these features are in operation.

Pre-ARM v8.3 processors will ignore Pointer Authentication instructions, so code built with this flag will continue to work on older processors, though without any of the intended protections. If enabling this flag, it is recommended to ensure the resultant packages are tested against an ARM v8.3+ linux system with known-working Pointer Authentication support so that any breakage caused by this feature is actually detected.


Title: Hardening Flags: shadowstack, trivialautovarinit, and pacret
Summary
This section describes three more hardening flags. `shadowstack` enhances security by using a separate stack for return addresses, but can break code with advanced stack management and requires testing on systems with CET support. `trivialautovarinit` initializes uninitialized stack variables with a non-zero value to prevent exploitation, but may interfere with tools like valgrind. `pacret` uses ARM's Pointer Authentication to protect return pointers, dramatically increasing the difficulty of ROP exploits, but can also cause issues with stack manipulation and requires testing on ARM v8.3+ systems.