1*67e74705SXin Li========= 2*67e74705SXin LiSafeStack 3*67e74705SXin Li========= 4*67e74705SXin Li 5*67e74705SXin Li.. contents:: 6*67e74705SXin Li :local: 7*67e74705SXin Li 8*67e74705SXin LiIntroduction 9*67e74705SXin Li============ 10*67e74705SXin Li 11*67e74705SXin LiSafeStack is an instrumentation pass that protects programs against attacks 12*67e74705SXin Libased on stack buffer overflows, without introducing any measurable performance 13*67e74705SXin Lioverhead. It works by separating the program stack into two distinct regions: 14*67e74705SXin Lithe safe stack and the unsafe stack. The safe stack stores return addresses, 15*67e74705SXin Liregister spills, and local variables that are always accessed in a safe way, 16*67e74705SXin Liwhile the unsafe stack stores everything else. This separation ensures that 17*67e74705SXin Libuffer overflows on the unsafe stack cannot be used to overwrite anything 18*67e74705SXin Lion the safe stack. 19*67e74705SXin Li 20*67e74705SXin LiSafeStack is a part of the `Code-Pointer Integrity (CPI) Project 21*67e74705SXin Li<http://dslab.epfl.ch/proj/cpi/>`_. 22*67e74705SXin Li 23*67e74705SXin LiPerformance 24*67e74705SXin Li----------- 25*67e74705SXin Li 26*67e74705SXin LiThe performance overhead of the SafeStack instrumentation is less than 0.1% on 27*67e74705SXin Liaverage across a variety of benchmarks (see the `Code-Pointer Integrity 28*67e74705SXin Li<http://dslab.epfl.ch/pubs/cpi.pdf>`__ paper for details). This is mainly 29*67e74705SXin Libecause most small functions do not have any variables that require the unsafe 30*67e74705SXin Listack and, hence, do not need unsafe stack frames to be created. The cost of 31*67e74705SXin Licreating unsafe stack frames for large functions is amortized by the cost of 32*67e74705SXin Liexecuting the function. 33*67e74705SXin Li 34*67e74705SXin LiIn some cases, SafeStack actually improves the performance. Objects that end up 35*67e74705SXin Libeing moved to the unsafe stack are usually large arrays or variables that are 36*67e74705SXin Liused through multiple stack frames. Moving such objects away from the safe 37*67e74705SXin Listack increases the locality of frequently accessed values on the stack, such 38*67e74705SXin Lias register spills, return addresses, and small local variables. 39*67e74705SXin Li 40*67e74705SXin LiCompatibility 41*67e74705SXin Li------------- 42*67e74705SXin Li 43*67e74705SXin LiMost programs, static libraries, or individual files can be compiled 44*67e74705SXin Liwith SafeStack as is. SafeStack requires basic runtime support, which, on most 45*67e74705SXin Liplatforms, is implemented as a compiler-rt library that is automatically linked 46*67e74705SXin Liin when the program is compiled with SafeStack. 47*67e74705SXin Li 48*67e74705SXin LiLinking a DSO with SafeStack is not currently supported. 49*67e74705SXin Li 50*67e74705SXin LiKnown compatibility limitations 51*67e74705SXin Li~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52*67e74705SXin Li 53*67e74705SXin LiCertain code that relies on low-level stack manipulations requires adaption to 54*67e74705SXin Liwork with SafeStack. One example is mark-and-sweep garbage collection 55*67e74705SXin Liimplementations for C/C++ (e.g., Oilpan in chromium/blink), which must be 56*67e74705SXin Lichanged to look for the live pointers on both safe and unsafe stacks. 57*67e74705SXin Li 58*67e74705SXin LiSafeStack supports linking statically modules that are compiled with and 59*67e74705SXin Liwithout SafeStack. An executable compiled with SafeStack can load dynamic 60*67e74705SXin Lilibraries that are not compiled with SafeStack. At the moment, compiling 61*67e74705SXin Lidynamic libraries with SafeStack is not supported. 62*67e74705SXin Li 63*67e74705SXin LiSignal handlers that use ``sigaltstack()`` must not use the unsafe stack (see 64*67e74705SXin Li``__attribute__((no_sanitize("safe-stack")))`` below). 65*67e74705SXin Li 66*67e74705SXin LiPrograms that use APIs from ``ucontext.h`` are not supported yet. 67*67e74705SXin Li 68*67e74705SXin LiSecurity 69*67e74705SXin Li-------- 70*67e74705SXin Li 71*67e74705SXin LiSafeStack protects return addresses, spilled registers and local variables that 72*67e74705SXin Liare always accessed in a safe way by separating them in a dedicated safe stack 73*67e74705SXin Liregion. The safe stack is automatically protected against stack-based buffer 74*67e74705SXin Lioverflows, since it is disjoint from the unsafe stack in memory, and it itself 75*67e74705SXin Liis always accessed in a safe way. In the current implementation, the safe stack 76*67e74705SXin Liis protected against arbitrary memory write vulnerabilities though 77*67e74705SXin Lirandomization and information hiding: the safe stack is allocated at a random 78*67e74705SXin Liaddress and the instrumentation ensures that no pointers to the safe stack are 79*67e74705SXin Liever stored outside of the safe stack itself (see limitations below). 80*67e74705SXin Li 81*67e74705SXin LiKnown security limitations 82*67e74705SXin Li~~~~~~~~~~~~~~~~~~~~~~~~~~ 83*67e74705SXin Li 84*67e74705SXin LiA complete protection against control-flow hijack attacks requires combining 85*67e74705SXin LiSafeStack with another mechanism that enforces the integrity of code pointers 86*67e74705SXin Lithat are stored on the heap or the unsafe stack, such as `CPI 87*67e74705SXin Li<http://dslab.epfl.ch/proj/cpi/>`_, or a forward-edge control flow integrity 88*67e74705SXin Limechanism that enforces correct calling conventions at indirect call sites, 89*67e74705SXin Lisuch as `IFCC <http://research.google.com/pubs/archive/42808.pdf>`_ with arity 90*67e74705SXin Lichecks. Clang has control-flow integrity protection scheme for :doc:`C++ virtual 91*67e74705SXin Licalls <ControlFlowIntegrity>`, but not non-virtual indirect calls. With 92*67e74705SXin LiSafeStack alone, an attacker can overwrite a function pointer on the heap or 93*67e74705SXin Lithe unsafe stack and cause a program to call arbitrary location, which in turn 94*67e74705SXin Limight enable stack pivoting and return-oriented programming. 95*67e74705SXin Li 96*67e74705SXin LiIn its current implementation, SafeStack provides precise protection against 97*67e74705SXin Listack-based buffer overflows, but protection against arbitrary memory write 98*67e74705SXin Livulnerabilities is probabilistic and relies on randomization and information 99*67e74705SXin Lihiding. The randomization is currently based on system-enforced ASLR and shares 100*67e74705SXin Liits known security limitations. The safe stack pointer hiding is not perfect 101*67e74705SXin Liyet either: system library functions such as ``swapcontext``, exception 102*67e74705SXin Lihandling mechanisms, intrinsics such as ``__builtin_frame_address``, or 103*67e74705SXin Lilow-level bugs in runtime support could leak the safe stack pointer. In the 104*67e74705SXin Lifuture, such leaks could be detected by static or dynamic analysis tools and 105*67e74705SXin Liprevented by adjusting such functions to either encrypt the stack pointer when 106*67e74705SXin Listoring it in the heap (as already done e.g., by ``setjmp``/``longjmp`` 107*67e74705SXin Liimplementation in glibc), or store it in a safe region instead. 108*67e74705SXin Li 109*67e74705SXin LiThe `CPI paper <http://dslab.epfl.ch/pubs/cpi.pdf>`_ describes two alternative, 110*67e74705SXin Listronger safe stack protection mechanisms, that rely on software fault 111*67e74705SXin Liisolation, or hardware segmentation (as available on x86-32 and some x86-64 112*67e74705SXin LiCPUs). 113*67e74705SXin Li 114*67e74705SXin LiAt the moment, SafeStack assumes that the compiler's implementation is correct. 115*67e74705SXin LiThis has not been verified except through manual code inspection, and could 116*67e74705SXin Lialways regress in the future. It's therefore desirable to have a separate 117*67e74705SXin Listatic or dynamic binary verification tool that would check the correctness of 118*67e74705SXin Lithe SafeStack instrumentation in final binaries. 119*67e74705SXin Li 120*67e74705SXin LiUsage 121*67e74705SXin Li===== 122*67e74705SXin Li 123*67e74705SXin LiTo enable SafeStack, just pass ``-fsanitize=safe-stack`` flag to both compile 124*67e74705SXin Liand link command lines. 125*67e74705SXin Li 126*67e74705SXin LiSupported Platforms 127*67e74705SXin Li------------------- 128*67e74705SXin Li 129*67e74705SXin LiSafeStack was tested on Linux, FreeBSD and MacOSX. 130*67e74705SXin Li 131*67e74705SXin LiLow-level API 132*67e74705SXin Li------------- 133*67e74705SXin Li 134*67e74705SXin Li``__has_feature(safe_stack)`` 135*67e74705SXin Li~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136*67e74705SXin Li 137*67e74705SXin LiIn some rare cases one may need to execute different code depending on 138*67e74705SXin Liwhether SafeStack is enabled. The macro ``__has_feature(safe_stack)`` can 139*67e74705SXin Libe used for this purpose. 140*67e74705SXin Li 141*67e74705SXin Li.. code-block:: c 142*67e74705SXin Li 143*67e74705SXin Li #if __has_feature(safe_stack) 144*67e74705SXin Li // code that builds only under SafeStack 145*67e74705SXin Li #endif 146*67e74705SXin Li 147*67e74705SXin Li``__attribute__((no_sanitize("safe-stack")))`` 148*67e74705SXin Li~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 149*67e74705SXin Li 150*67e74705SXin LiUse ``__attribute__((no_sanitize("safe-stack")))`` on a function declaration 151*67e74705SXin Lito specify that the safe stack instrumentation should not be applied to that 152*67e74705SXin Lifunction, even if enabled globally (see ``-fsanitize=safe-stack`` flag). This 153*67e74705SXin Liattribute may be required for functions that make assumptions about the 154*67e74705SXin Liexact layout of their stack frames. 155*67e74705SXin Li 156*67e74705SXin LiAll local variables in functions with this attribute will be stored on the safe 157*67e74705SXin Listack. The safe stack remains unprotected against memory errors when accessing 158*67e74705SXin Lithese variables, so extra care must be taken to manually ensure that all such 159*67e74705SXin Liaccesses are safe. Furthermore, the addresses of such local variables should 160*67e74705SXin Linever be stored on the heap, as it would leak the location of the SafeStack. 161*67e74705SXin Li 162*67e74705SXin Li``__builtin___get_unsafe_stack_ptr()`` 163*67e74705SXin Li~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 164*67e74705SXin Li 165*67e74705SXin LiThis builtin function returns current unsafe stack pointer of the current 166*67e74705SXin Lithread. 167*67e74705SXin Li 168*67e74705SXin Li``__builtin___get_unsafe_stack_start()`` 169*67e74705SXin Li~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 170*67e74705SXin Li 171*67e74705SXin LiThis builtin function returns a pointer to the start of the unsafe stack of the 172*67e74705SXin Licurrent thread. 173*67e74705SXin Li 174*67e74705SXin LiDesign 175*67e74705SXin Li====== 176*67e74705SXin Li 177*67e74705SXin LiPlease refer to the `Code-Pointer Integrity <http://dslab.epfl.ch/proj/cpi/>`__ 178*67e74705SXin Liproject page for more information about the design of the SafeStack and its 179*67e74705SXin Lirelated technologies. 180*67e74705SXin Li 181*67e74705SXin Lisetjmp and exception handling 182*67e74705SXin Li----------------------------- 183*67e74705SXin Li 184*67e74705SXin LiThe `OSDI'14 paper <http://dslab.epfl.ch/pubs/cpi.pdf>`_ mentions that 185*67e74705SXin Lion Linux the instrumentation pass finds calls to setjmp or functions that 186*67e74705SXin Limay throw an exception, and inserts required instrumentation at their call 187*67e74705SXin Lisites. Specifically, the instrumentation pass saves the shadow stack pointer 188*67e74705SXin Lion the safe stack before the call site, and restores it either after the 189*67e74705SXin Licall to setjmp or after an exception has been caught. This is implemented 190*67e74705SXin Liin the function ``SafeStack::createStackRestorePoints``. 191*67e74705SXin Li 192*67e74705SXin LiPublications 193*67e74705SXin Li------------ 194*67e74705SXin Li 195*67e74705SXin Li`Code-Pointer Integrity <http://dslab.epfl.ch/pubs/cpi.pdf>`__. 196*67e74705SXin LiVolodymyr Kuznetsov, Laszlo Szekeres, Mathias Payer, George Candea, R. Sekar, Dawn Song. 197*67e74705SXin LiUSENIX Symposium on Operating Systems Design and Implementation 198*67e74705SXin Li(`OSDI <https://www.usenix.org/conference/osdi14>`_), Broomfield, CO, October 2014 199