1========= 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 18on the safe stack. 19 20SafeStack is a part of the `Code-Pointer Integrity (CPI) Project 21<https://dslab.epfl.ch/proj/cpi/>`_. 22 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 28<https://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly 29because 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 40Compatibility 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 58SafeStack 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. 62 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 68Security 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 87<https://dslab.epfl.ch/proj/cpi/>`_, or a forward-edge control flow integrity 88mechanism that enforces correct calling conventions at indirect call sites, 89such as `IFCC <https://research.google.com/pubs/archive/42808.pdf>`_ with arity 90checks. Clang has control-flow integrity protection scheme for :doc:`C++ virtual 91calls <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 109The `CPI paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative, 110stronger 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 120Usage 121===== 122 123To enable SafeStack, just pass ``-fsanitize=safe-stack`` flag to both compile 124and link command lines. 125 126Supported Platforms 127------------------- 128 129SafeStack was tested on Linux, NetBSD, FreeBSD and macOS. 130 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 156All 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. 161 162``__builtin___get_unsafe_stack_ptr()`` 163~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 164 165This builtin function returns current unsafe stack pointer of the current 166thread. 167 168``__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 180``__builtin___get_unsafe_stack_start()`` 181~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182 183Deprecated: This builtin function is an alias for 184``__builtin___get_unsafe_stack_bottom()``. 185 186Design 187====== 188 189Please refer to the `Code-Pointer Integrity <https://dslab.epfl.ch/proj/cpi/>`__ 190project page for more information about the design of the SafeStack and its 191related technologies. 192 193setjmp and exception handling 194----------------------------- 195 196The `OSDI'14 paper <https://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that 197on 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 204Publications 205------------ 206 207`Code-Pointer Integrity <https://dslab.epfl.ch/pubs/cpi.pdf>`__. 208Volodymyr 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 211