Introducing SafeStack in HardenedBSD

SafeStack is an exploit mitigation technique that creates two stacks: one for data that needs to be kept safe, such as return addresses and function pointers; and an unsafe stack for everything else. SafeStack promises a low performance penalty (typically around 0.1%).

SafeStack requires both ASLR and W^X in order to be effective. With HardenedBSD satisfying both of those prerequisites, SafeStack was deemed to be an excellent candidate for default inclusion in HardenedBSD. Starting with HardenedBSD 12-CURRENT, it is enabled by default for amd64. Support for non-amd64 architectures is limited by upstream clang.

As of 28 November 2016, with clang 3.9.0, SafeStack only supports being applied to applications and not shared libraries. Multiple patches have been submitted to clang by third parties to add support for shared libraries. As such, SafeStack is still undergoing active development.

SafeStack has been made available to the HardenedBSD ports tree as well. Unlike PIE and RELRO+BIND_NOW, it is not enabled globally for the ports tree. Some ports, like ports-mgmt/pkg have SafeStack enabled by default. Only those ports that have been tested to work fine will have SafeStack enabled by default. Users are able to toggle SafeStack by using the config target. Additionally, the SafeStack option is only applicable to amd64 architectures. Attempting to enable SafeStack for a non-amd64 port build will result in a NO-OP. SafeStack will simply not be applied.

Here's some good weekend reading for you if you'd like more info about SafeStack and CFI/CPI in general:

  1. SafeStack - Clang documentation
  2. Fine-Grained Control-Flow Integrity through Binary Hardening (PDF)
  3. Control-Flow Bending: On the Effectiveness of Control-Flow Integrity (PDF
  4. Code-Pointer Integrity (PDF)