blob: c585315dff882afbd56e2fb55f2308243de1314a [file] [log] [blame]
Peter Collingbournec4122c12015-06-15 21:08:131=========
2SafeStack
3=========
4
5.. contents::
6 :local:
7
8Introduction
9============
10
11SafeStack is an instrumentation pass that protects programs against attacks
12based on stack buffer overflows, without introducing any measurable performance
13overhead. It works by separating the program stack into two distinct regions:
14the safe stack and the unsafe stack. The safe stack stores return addresses,
15register spills, and local variables that are always accessed in a safe way,
16while the unsafe stack stores everything else. This separation ensures that
17buffer overflows on the unsafe stack cannot be used to overwrite anything
Peter Collingbourne7ce91992015-06-23 22:24:4518on the safe stack.
19
20SafeStack is a part of the `Code-Pointer Integrity (CPI) Project
ksyx45b278f2022-06-11 14:59:5121<https://dslab.epfl.ch/research/cpi/>`_.
Peter Collingbournec4122c12015-06-15 21:08:1322
23Performance
24-----------
25
26The performance overhead of the SafeStack instrumentation is less than 0.1% on
27average across a variety of benchmarks (see the `Code-Pointer Integrity
Eugene Zelenko92602e22019-01-23 20:51:0628<https://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly
Peter Collingbournec4122c12015-06-15 21:08:1329because most small functions do not have any variables that require the unsafe
30stack and, hence, do not need unsafe stack frames to be created. The cost of
31creating unsafe stack frames for large functions is amortized by the cost of
32executing the function.
33
34In some cases, SafeStack actually improves the performance. Objects that end up
35being moved to the unsafe stack are usually large arrays or variables that are
36used through multiple stack frames. Moving such objects away from the safe
37stack increases the locality of frequently accessed values on the stack, such
38as register spills, return addresses, and small local variables.
39
Peter Collingbournec4122c12015-06-15 21:08:1340Compatibility
41-------------
42
43Most programs, static libraries, or individual files can be compiled
44with SafeStack as is. SafeStack requires basic runtime support, which, on most
45platforms, is implemented as a compiler-rt library that is automatically linked
46in when the program is compiled with SafeStack.
47
48Linking a DSO with SafeStack is not currently supported.
49
50Known compatibility limitations
51~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52
53Certain code that relies on low-level stack manipulations requires adaption to
54work with SafeStack. One example is mark-and-sweep garbage collection
55implementations for C/C++ (e.g., Oilpan in chromium/blink), which must be
56changed to look for the live pointers on both safe and unsafe stacks.
57
Peter Collingbourne7ce91992015-06-23 22:24:4558SafeStack supports linking statically modules that are compiled with and
59without SafeStack. An executable compiled with SafeStack can load dynamic
60libraries that are not compiled with SafeStack. At the moment, compiling
61dynamic libraries with SafeStack is not supported.
Peter Collingbournec4122c12015-06-15 21:08:1362
63Signal handlers that use ``sigaltstack()`` must not use the unsafe stack (see
64``__attribute__((no_sanitize("safe-stack")))`` below).
65
66Programs that use APIs from ``ucontext.h`` are not supported yet.
67
Peter Collingbourne7ce91992015-06-23 22:24:4568Security
69--------
70
71SafeStack protects return addresses, spilled registers and local variables that
72are always accessed in a safe way by separating them in a dedicated safe stack
73region. The safe stack is automatically protected against stack-based buffer
74overflows, since it is disjoint from the unsafe stack in memory, and it itself
75is always accessed in a safe way. In the current implementation, the safe stack
76is protected against arbitrary memory write vulnerabilities though
77randomization and information hiding: the safe stack is allocated at a random
78address and the instrumentation ensures that no pointers to the safe stack are
79ever stored outside of the safe stack itself (see limitations below).
80
81Known security limitations
82~~~~~~~~~~~~~~~~~~~~~~~~~~
83
84A complete protection against control-flow hijack attacks requires combining
85SafeStack with another mechanism that enforces the integrity of code pointers
86that are stored on the heap or the unsafe stack, such as `CPI
ksyx45b278f2022-06-11 14:59:5187<https://dslab.epfl.ch/research/cpi/>`_, or a forward-edge control flow integrity
Peter Collingbourne7ce91992015-06-23 22:24:4588mechanism that enforces correct calling conventions at indirect call sites,
Eugene Zelenkoadcb3f52019-01-23 20:39:0789such as `IFCC <https://research.google.com/pubs/archive/42808.pdf>`_ with arity
Peter Collingbourne5b745932015-06-25 21:02:1790checks. Clang has control-flow integrity protection scheme for :doc:`C++ virtual
Peter Collingbourne7ce91992015-06-23 22:24:4591calls <ControlFlowIntegrity>`, but not non-virtual indirect calls. With
92SafeStack alone, an attacker can overwrite a function pointer on the heap or
93the unsafe stack and cause a program to call arbitrary location, which in turn
94might enable stack pivoting and return-oriented programming.
95
96In its current implementation, SafeStack provides precise protection against
97stack-based buffer overflows, but protection against arbitrary memory write
98vulnerabilities is probabilistic and relies on randomization and information
99hiding. The randomization is currently based on system-enforced ASLR and shares
100its known security limitations. The safe stack pointer hiding is not perfect
101yet either: system library functions such as ``swapcontext``, exception
102handling mechanisms, intrinsics such as ``__builtin_frame_address``, or
103low-level bugs in runtime support could leak the safe stack pointer. In the
104future, such leaks could be detected by static or dynamic analysis tools and
105prevented by adjusting such functions to either encrypt the stack pointer when
106storing it in the heap (as already done e.g., by ``setjmp``/``longjmp``
107implementation in glibc), or store it in a safe region instead.
108
Eugene Zelenkoadcb3f52019-01-23 20:39:07109The `CPI paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative,
Peter Collingbourne7ce91992015-06-23 22:24:45110stronger safe stack protection mechanisms, that rely on software fault
111isolation, or hardware segmentation (as available on x86-32 and some x86-64
112CPUs).
113
114At the moment, SafeStack assumes that the compiler's implementation is correct.
115This has not been verified except through manual code inspection, and could
116always regress in the future. It's therefore desirable to have a separate
117static or dynamic binary verification tool that would check the correctness of
118the SafeStack instrumentation in final binaries.
119
Peter Collingbournec4122c12015-06-15 21:08:13120Usage
121=====
122
Peter Collingbourne7ce91992015-06-23 22:24:45123To enable SafeStack, just pass ``-fsanitize=safe-stack`` flag to both compile
124and link command lines.
Peter Collingbournec4122c12015-06-15 21:08:13125
126Supported Platforms
127-------------------
128
J. Ryan Stinnettd45eaf92019-05-30 16:46:22129SafeStack was tested on Linux, NetBSD, FreeBSD and macOS.
Peter Collingbournec4122c12015-06-15 21:08:13130
131Low-level API
132-------------
133
134``__has_feature(safe_stack)``
135~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136
137In some rare cases one may need to execute different code depending on
138whether SafeStack is enabled. The macro ``__has_feature(safe_stack)`` can
139be used for this purpose.
140
141.. code-block:: c
142
143 #if __has_feature(safe_stack)
144 // code that builds only under SafeStack
145 #endif
146
147``__attribute__((no_sanitize("safe-stack")))``
148~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
149
150Use ``__attribute__((no_sanitize("safe-stack")))`` on a function declaration
151to specify that the safe stack instrumentation should not be applied to that
152function, even if enabled globally (see ``-fsanitize=safe-stack`` flag). This
153attribute may be required for functions that make assumptions about the
154exact layout of their stack frames.
155
Peter Collingbourne7ce91992015-06-23 22:24:45156All local variables in functions with this attribute will be stored on the safe
157stack. The safe stack remains unprotected against memory errors when accessing
158these variables, so extra care must be taken to manually ensure that all such
159accesses are safe. Furthermore, the addresses of such local variables should
160never be stored on the heap, as it would leak the location of the SafeStack.
Peter Collingbournec4122c12015-06-15 21:08:13161
162``__builtin___get_unsafe_stack_ptr()``
163~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164
165This builtin function returns current unsafe stack pointer of the current
166thread.
167
Vlad Tsyrklevichbe9a9fd2018-07-13 19:48:35168``__builtin___get_unsafe_stack_bottom()``
169~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
170
171This builtin function returns a pointer to the bottom of the unsafe stack of the
172current thread.
173
174``__builtin___get_unsafe_stack_top()``
175~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176
177This builtin function returns a pointer to the top of the unsafe stack of the
178current thread.
179
Peter Collingbournec4122c12015-06-15 21:08:13180``__builtin___get_unsafe_stack_start()``
181~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182
Vlad Tsyrklevichbe9a9fd2018-07-13 19:48:35183Deprecated: This builtin function is an alias for
184``__builtin___get_unsafe_stack_bottom()``.
Peter Collingbournec4122c12015-06-15 21:08:13185
186Design
187======
188
ksyx45b278f2022-06-11 14:59:51189Please refer to the `Code-Pointer Integrity <https://dslab.epfl.ch/research/cpi/>`__
Peter Collingbourne7ce91992015-06-23 22:24:45190project page for more information about the design of the SafeStack and its
191related technologies.
Peter Collingbournec4122c12015-06-15 21:08:13192
Peter Collingbournea9f38982016-05-24 23:38:02193setjmp and exception handling
194-----------------------------
195
Eugene Zelenkoadcb3f52019-01-23 20:39:07196The `OSDI'14 paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that
Peter Collingbournea9f38982016-05-24 23:38:02197on Linux the instrumentation pass finds calls to setjmp or functions that
198may throw an exception, and inserts required instrumentation at their call
199sites. Specifically, the instrumentation pass saves the shadow stack pointer
200on the safe stack before the call site, and restores it either after the
201call to setjmp or after an exception has been caught. This is implemented
202in the function ``SafeStack::createStackRestorePoints``.
203
Peter Collingbournec4122c12015-06-15 21:08:13204Publications
205------------
206
Eugene Zelenko92602e22019-01-23 20:51:06207`Code-Pointer Integrity <https://dslab.epfl.ch/pubs/cpi.pdf>`__.
Peter Collingbournec4122c12015-06-15 21:08:13208Volodymyr Kuznetsov, Laszlo Szekeres, Mathias Payer, George Candea, R. Sekar, Dawn Song.
209USENIX Symposium on Operating Systems Design and Implementation
210(`OSDI <https://www.usenix.org/conference/osdi14>`_), Broomfield, CO, October 2014