xref: /aosp_15_r20/external/clang/docs/SafeStack.rst (revision 67e74705e28f6214e480b399dd47ea732279e315)
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