11 SafeStack is an instrumentation pass that protects programs against attacks
12 based on stack buffer overflows, without introducing any measurable performance
13 overhead. It works by separating the program stack into two distinct regions:
14 the safe stack and the unsafe stack. The safe stack stores return addresses,
15 register spills, and local variables that are always accessed in a safe way,
16 while the unsafe stack stores everything else. This separation ensures that
17 buffer overflows on the unsafe stack cannot be used to overwrite anything
20 SafeStack is a part of the `Code-Pointer Integrity (CPI) Project
21 <https://dslab.epfl.ch/research/cpi/>`_.
26 The performance overhead of the SafeStack instrumentation is less than 0.1% on
27 average across a variety of benchmarks (see the `Code-Pointer Integrity
28 <https://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly
29 because most small functions do not have any variables that require the unsafe
30 stack and, hence, do not need unsafe stack frames to be created. The cost of
31 creating unsafe stack frames for large functions is amortized by the cost of
32 executing the function.
34 In some cases, SafeStack actually improves the performance. Objects that end up
35 being moved to the unsafe stack are usually large arrays or variables that are
36 used through multiple stack frames. Moving such objects away from the safe
37 stack increases the locality of frequently accessed values on the stack, such
38 as register spills, return addresses, and small local variables.
43 Most programs, static libraries, or individual files can be compiled
44 with SafeStack as is. SafeStack requires basic runtime support, which, on most
45 platforms, is implemented as a compiler-rt library that is automatically linked
46 in when the program is compiled with SafeStack.
48 Linking a DSO with SafeStack is not currently supported.
50 Known compatibility limitations
51 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
53 Certain code that relies on low-level stack manipulations requires adaption to
54 work with SafeStack. One example is mark-and-sweep garbage collection
55 implementations for C/C++ (e.g., Oilpan in chromium/blink), which must be
56 changed to look for the live pointers on both safe and unsafe stacks.
58 SafeStack supports linking statically modules that are compiled with and
59 without SafeStack. An executable compiled with SafeStack can load dynamic
60 libraries that are not compiled with SafeStack. At the moment, compiling
61 dynamic libraries with SafeStack is not supported.
63 Signal handlers that use ``sigaltstack()`` must not use the unsafe stack (see
64 ``__attribute__((no_sanitize("safe-stack")))`` below).
66 Programs that use APIs from ``ucontext.h`` are not supported yet.
71 SafeStack protects return addresses, spilled registers and local variables that
72 are always accessed in a safe way by separating them in a dedicated safe stack
73 region. The safe stack is automatically protected against stack-based buffer
74 overflows, since it is disjoint from the unsafe stack in memory, and it itself
75 is always accessed in a safe way. In the current implementation, the safe stack
76 is protected against arbitrary memory write vulnerabilities though
77 randomization and information hiding: the safe stack is allocated at a random
78 address and the instrumentation ensures that no pointers to the safe stack are
79 ever stored outside of the safe stack itself (see limitations below).
81 Known security limitations
82 ~~~~~~~~~~~~~~~~~~~~~~~~~~
84 A complete protection against control-flow hijack attacks requires combining
85 SafeStack with another mechanism that enforces the integrity of code pointers
86 that are stored on the heap or the unsafe stack, such as `CPI
87 <https://dslab.epfl.ch/research/cpi/>`_, or a forward-edge control flow integrity
88 mechanism that enforces correct calling conventions at indirect call sites,
89 such as `IFCC <https://research.google.com/pubs/archive/42808.pdf>`_ with arity
90 checks. Clang has control-flow integrity protection scheme for :doc:`C++ virtual
91 calls <ControlFlowIntegrity>`, but not non-virtual indirect calls. With
92 SafeStack alone, an attacker can overwrite a function pointer on the heap or
93 the unsafe stack and cause a program to call arbitrary location, which in turn
94 might enable stack pivoting and return-oriented programming.
96 In its current implementation, SafeStack provides precise protection against
97 stack-based buffer overflows, but protection against arbitrary memory write
98 vulnerabilities is probabilistic and relies on randomization and information
99 hiding. The randomization is currently based on system-enforced ASLR and shares
100 its known security limitations. The safe stack pointer hiding is not perfect
101 yet either: system library functions such as ``swapcontext``, exception
102 handling mechanisms, intrinsics such as ``__builtin_frame_address``, or
103 low-level bugs in runtime support could leak the safe stack pointer. In the
104 future, such leaks could be detected by static or dynamic analysis tools and
105 prevented by adjusting such functions to either encrypt the stack pointer when
106 storing it in the heap (as already done e.g., by ``setjmp``/``longjmp``
107 implementation in glibc), or store it in a safe region instead.
109 The `CPI paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative,
110 stronger safe stack protection mechanisms, that rely on software fault
111 isolation, or hardware segmentation (as available on x86-32 and some x86-64
114 At the moment, SafeStack assumes that the compiler's implementation is correct.
115 This has not been verified except through manual code inspection, and could
116 always regress in the future. It's therefore desirable to have a separate
117 static or dynamic binary verification tool that would check the correctness of
118 the SafeStack instrumentation in final binaries.
123 To enable SafeStack, just pass ``-fsanitize=safe-stack`` flag to both compile
124 and link command lines.
129 SafeStack was tested on Linux, NetBSD, FreeBSD and macOS.
134 ``__has_feature(safe_stack)``
135 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
137 In some rare cases one may need to execute different code depending on
138 whether SafeStack is enabled. The macro ``__has_feature(safe_stack)`` can
139 be used for this purpose.
143 #if __has_feature(safe_stack)
144 // code that builds only under SafeStack
147 ``__attribute__((no_sanitize("safe-stack")))``
148 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150 Use ``__attribute__((no_sanitize("safe-stack")))`` on a function declaration
151 to specify that the safe stack instrumentation should not be applied to that
152 function, even if enabled globally (see ``-fsanitize=safe-stack`` flag). This
153 attribute may be required for functions that make assumptions about the
154 exact layout of their stack frames.
156 All local variables in functions with this attribute will be stored on the safe
157 stack. The safe stack remains unprotected against memory errors when accessing
158 these variables, so extra care must be taken to manually ensure that all such
159 accesses are safe. Furthermore, the addresses of such local variables should
160 never be stored on the heap, as it would leak the location of the SafeStack.
162 ``__builtin___get_unsafe_stack_ptr()``
163 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
165 This builtin function returns current unsafe stack pointer of the current
168 ``__builtin___get_unsafe_stack_bottom()``
169 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171 This builtin function returns a pointer to the bottom of the unsafe stack of the
174 ``__builtin___get_unsafe_stack_top()``
175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
177 This builtin function returns a pointer to the top of the unsafe stack of the
180 ``__builtin___get_unsafe_stack_start()``
181 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
183 Deprecated: This builtin function is an alias for
184 ``__builtin___get_unsafe_stack_bottom()``.
189 Please refer to the `Code-Pointer Integrity <https://dslab.epfl.ch/research/cpi/>`__
190 project page for more information about the design of the SafeStack and its
191 related technologies.
193 setjmp and exception handling
194 -----------------------------
196 The `OSDI'14 paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that
197 on Linux the instrumentation pass finds calls to setjmp or functions that
198 may throw an exception, and inserts required instrumentation at their call
199 sites. Specifically, the instrumentation pass saves the shadow stack pointer
200 on the safe stack before the call site, and restores it either after the
201 call to setjmp or after an exception has been caught. This is implemented
202 in the function ``SafeStack::createStackRestorePoints``.
207 `Code-Pointer Integrity <https://dslab.epfl.ch/pubs/cpi.pdf>`__.
208 Volodymyr Kuznetsov, Laszlo Szekeres, Mathias Payer, George Candea, R. Sekar, Dawn Song.
209 USENIX Symposium on Operating Systems Design and Implementation
210 (`OSDI <https://www.usenix.org/conference/osdi14>`_), Broomfield, CO, October 2014