1 | ====================== |
2 | Control Flow Integrity |
3 | ====================== |
4 | |
5 | .. toctree:: |
6 | :hidden: |
7 | |
8 | ControlFlowIntegrityDesign |
9 | |
10 | .. contents:: |
11 | :local: |
12 | |
13 | Introduction |
14 | ============ |
15 | |
16 | Clang includes an implementation of a number of control flow integrity (CFI) |
17 | schemes, which are designed to abort the program upon detecting certain forms |
18 | of undefined behavior that can potentially allow attackers to subvert the |
19 | program's control flow. These schemes have been optimized for performance, |
20 | allowing developers to enable them in release builds. |
21 | |
22 | To enable Clang's available CFI schemes, use the flag ``-fsanitize=cfi``. |
23 | You can also enable a subset of available :ref:`schemes <cfi-schemes>`. |
24 | As currently implemented, all schemes rely on link-time optimization (LTO); |
25 | so it is required to specify ``-flto``, and the linker used must support LTO, |
26 | for example via the `gold plugin`_. |
27 | |
28 | To allow the checks to be implemented efficiently, the program must |
29 | be structured such that certain object files are compiled with CFI |
30 | enabled, and are statically linked into the program. This may preclude |
31 | the use of shared libraries in some cases. |
32 | |
33 | The compiler will only produce CFI checks for a class if it can infer hidden |
34 | LTO visibility for that class. LTO visibility is a property of a class that |
35 | is inferred from flags and attributes. For more details, see the documentation |
36 | for :doc:`LTO visibility <LTOVisibility>`. |
37 | |
38 | The ``-fsanitize=cfi-{vcall,nvcall,derived-cast,unrelated-cast}`` flags |
39 | require that a ``-fvisibility=`` flag also be specified. This is because the |
40 | default visibility setting is ``-fvisibility=default``, which would disable |
41 | CFI checks for classes without visibility attributes. Most users will want |
42 | to specify ``-fvisibility=hidden``, which enables CFI checks for such classes. |
43 | |
44 | Experimental support for :ref:`cross-DSO control flow integrity |
45 | <cfi-cross-dso>` exists that does not require classes to have hidden LTO |
46 | visibility. This cross-DSO support has unstable ABI at this time. |
47 | |
48 | .. _gold plugin: https://llvm.org/docs/GoldPlugin.html |
49 | |
50 | .. _cfi-schemes: |
51 | |
52 | Available schemes |
53 | ================= |
54 | |
55 | Available schemes are: |
56 | |
57 | - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks |
58 | <cfi-strictness>`. |
59 | - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong |
60 | dynamic type. |
61 | - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another |
62 | unrelated type to the wrong dynamic type. |
63 | - ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of |
64 | the wrong dynamic type. |
65 | - ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the |
66 | wrong dynamic type. |
67 | - ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic |
68 | type. |
69 | - ``-fsanitize=cfi-mfcall``: Indirect call via a member function pointer with |
70 | wrong dynamic type. |
71 | |
72 | You can use ``-fsanitize=cfi`` to enable all the schemes and use |
73 | ``-fno-sanitize`` flag to narrow down the set of schemes as desired. |
74 | For example, you can build your program with |
75 | ``-fsanitize=cfi -fno-sanitize=cfi-nvcall,cfi-icall`` |
76 | to use all schemes except for non-virtual member function call and indirect call |
77 | checking. |
78 | |
79 | Remember that you have to provide ``-flto`` if at least one CFI scheme is |
80 | enabled. |
81 | |
82 | Trapping and Diagnostics |
83 | ======================== |
84 | |
85 | By default, CFI will abort the program immediately upon detecting a control |
86 | flow integrity violation. You can use the :ref:`-fno-sanitize-trap= |
87 | <controlling-code-generation>` flag to cause CFI to print a diagnostic |
88 | similar to the one below before the program aborts. |
89 | |
90 | .. code-block:: console |
91 | |
92 | bad-cast.cpp:109:7: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast (vtable address 0x000000425a50) |
93 | 0x000000425a50: note: vtable is of type 'A' |
94 | 00 00 00 00 f0 f1 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 5a 42 00 |
95 | ^ |
96 | |
97 | If diagnostics are enabled, you can also configure CFI to continue program |
98 | execution instead of aborting by using the :ref:`-fsanitize-recover= |
99 | <controlling-code-generation>` flag. |
100 | |
101 | Forward-Edge CFI for Virtual Calls |
102 | ================================== |
103 | |
104 | This scheme checks that virtual calls take place using a vptr of the correct |
105 | dynamic type; that is, the dynamic type of the called object must be a |
106 | derived class of the static type of the object used to make the call. |
107 | This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``. |
108 | |
109 | For this scheme to work, all translation units containing the definition |
110 | of a virtual member function (whether inline or not), other than members |
111 | of :ref:`blacklisted <cfi-blacklist>` types or types with public :doc:`LTO |
112 | visibility <LTOVisibility>`, must be compiled with ``-flto`` or ``-flto=thin`` |
113 | enabled and be statically linked into the program. |
114 | |
115 | Performance |
116 | ----------- |
117 | |
118 | A performance overhead of less than 1% has been measured by running the |
119 | Dromaeo benchmark suite against an instrumented version of the Chromium |
120 | web browser. Another good performance benchmark for this mechanism is the |
121 | virtual-call-heavy SPEC 2006 xalancbmk. |
122 | |
123 | Note that this scheme has not yet been optimized for binary size; an increase |
124 | of up to 15% has been observed for Chromium. |
125 | |
126 | Bad Cast Checking |
127 | ================= |
128 | |
129 | This scheme checks that pointer casts are made to an object of the correct |
130 | dynamic type; that is, the dynamic type of the object must be a derived class |
131 | of the pointee type of the cast. The checks are currently only introduced |
132 | where the class being casted to is a polymorphic class. |
133 | |
134 | Bad casts are not in themselves control flow integrity violations, but they |
135 | can also create security vulnerabilities, and the implementation uses many |
136 | of the same mechanisms. |
137 | |
138 | There are two types of bad cast that may be forbidden: bad casts |
139 | from a base class to a derived class (which can be checked with |
140 | ``-fsanitize=cfi-derived-cast``), and bad casts from a pointer of |
141 | type ``void*`` or another unrelated type (which can be checked with |
142 | ``-fsanitize=cfi-unrelated-cast``). |
143 | |
144 | The difference between these two types of casts is that the first is defined |
145 | by the C++ standard to produce an undefined value, while the second is not |
146 | in itself undefined behavior (it is well defined to cast the pointer back |
147 | to its original type) unless the object is uninitialized and the cast is a |
148 | ``static_cast`` (see C++14 [basic.life]p5). |
149 | |
150 | If a program as a matter of policy forbids the second type of cast, that |
151 | restriction can normally be enforced. However it may in some cases be necessary |
152 | for a function to perform a forbidden cast to conform with an external API |
153 | (e.g. the ``allocate`` member function of a standard library allocator). Such |
154 | functions may be :ref:`blacklisted <cfi-blacklist>`. |
155 | |
156 | For this scheme to work, all translation units containing the definition |
157 | of a virtual member function (whether inline or not), other than members |
158 | of :ref:`blacklisted <cfi-blacklist>` types or types with public :doc:`LTO |
159 | visibility <LTOVisibility>`, must be compiled with ``-flto`` or ``-flto=thin`` |
160 | enabled and be statically linked into the program. |
161 | |
162 | Non-Virtual Member Function Call Checking |
163 | ========================================= |
164 | |
165 | This scheme checks that non-virtual calls take place using an object of |
166 | the correct dynamic type; that is, the dynamic type of the called object |
167 | must be a derived class of the static type of the object used to make the |
168 | call. The checks are currently only introduced where the object is of a |
169 | polymorphic class type. This CFI scheme can be enabled on its own using |
170 | ``-fsanitize=cfi-nvcall``. |
171 | |
172 | For this scheme to work, all translation units containing the definition |
173 | of a virtual member function (whether inline or not), other than members |
174 | of :ref:`blacklisted <cfi-blacklist>` types or types with public :doc:`LTO |
175 | visibility <LTOVisibility>`, must be compiled with ``-flto`` or ``-flto=thin`` |
176 | enabled and be statically linked into the program. |
177 | |
178 | .. _cfi-strictness: |
179 | |
180 | Strictness |
181 | ---------- |
182 | |
183 | If a class has a single non-virtual base and does not introduce or override |
184 | virtual member functions or fields other than an implicitly defined virtual |
185 | destructor, it will have the same layout and virtual function semantics as |
186 | its base. By default, casts to such classes are checked as if they were made |
187 | to the least derived such class. |
188 | |
189 | Casting an instance of a base class to such a derived class is technically |
190 | undefined behavior, but it is a relatively common hack for introducing |
191 | member functions on class instances with specific properties that works under |
192 | most compilers and should not have security implications, so we allow it by |
193 | default. It can be disabled with ``-fsanitize=cfi-cast-strict``. |
194 | |
195 | Indirect Function Call Checking |
196 | =============================== |
197 | |
198 | This scheme checks that function calls take place using a function of the |
199 | correct dynamic type; that is, the dynamic type of the function must match |
200 | the static type used at the call. This CFI scheme can be enabled on its own |
201 | using ``-fsanitize=cfi-icall``. |
202 | |
203 | For this scheme to work, each indirect function call in the program, other |
204 | than calls in :ref:`blacklisted <cfi-blacklist>` functions, must call a |
205 | function which was either compiled with ``-fsanitize=cfi-icall`` enabled, |
206 | or whose address was taken by a function in a translation unit compiled with |
207 | ``-fsanitize=cfi-icall``. |
208 | |
209 | If a function in a translation unit compiled with ``-fsanitize=cfi-icall`` |
210 | takes the address of a function not compiled with ``-fsanitize=cfi-icall``, |
211 | that address may differ from the address taken by a function in a translation |
212 | unit not compiled with ``-fsanitize=cfi-icall``. This is technically a |
213 | violation of the C and C++ standards, but it should not affect most programs. |
214 | |
215 | Each translation unit compiled with ``-fsanitize=cfi-icall`` must be |
216 | statically linked into the program or shared library, and calls across |
217 | shared library boundaries are handled as if the callee was not compiled with |
218 | ``-fsanitize=cfi-icall``. |
219 | |
220 | This scheme is currently only supported on the x86 and x86_64 architectures. |
221 | |
222 | ``-fsanitize-cfi-icall-generalize-pointers`` |
223 | -------------------------------------------- |
224 | |
225 | Mismatched pointer types are a common cause of cfi-icall check failures. |
226 | Translation units compiled with the ``-fsanitize-cfi-icall-generalize-pointers`` |
227 | flag relax pointer type checking for call sites in that translation unit, |
228 | applied across all functions compiled with ``-fsanitize=cfi-icall``. |
229 | |
230 | Specifically, pointers in return and argument types are treated as equivalent as |
231 | long as the qualifiers for the type they point to match. For example, ``char*``, |
232 | ``char**``, and ``int*`` are considered equivalent types. However, ``char*`` and |
233 | ``const char*`` are considered separate types. |
234 | |
235 | ``-fsanitize-cfi-icall-generalize-pointers`` is not compatible with |
236 | ``-fsanitize-cfi-cross-dso``. |
237 | |
238 | |
239 | ``-fsanitize=cfi-icall`` and ``-fsanitize=function`` |
240 | ---------------------------------------------------- |
241 | |
242 | This tool is similar to ``-fsanitize=function`` in that both tools check |
243 | the types of function calls. However, the two tools occupy different points |
244 | on the design space; ``-fsanitize=function`` is a developer tool designed |
245 | to find bugs in local development builds, whereas ``-fsanitize=cfi-icall`` |
246 | is a security hardening mechanism designed to be deployed in release builds. |
247 | |
248 | ``-fsanitize=function`` has a higher space and time overhead due to a more |
249 | complex type check at indirect call sites, as well as a need for run-time |
250 | type information (RTTI), which may make it unsuitable for deployment. Because |
251 | of the need for RTTI, ``-fsanitize=function`` can only be used with C++ |
252 | programs, whereas ``-fsanitize=cfi-icall`` can protect both C and C++ programs. |
253 | |
254 | On the other hand, ``-fsanitize=function`` conforms more closely with the C++ |
255 | standard and user expectations around interaction with shared libraries; |
256 | the identity of function pointers is maintained, and calls across shared |
257 | library boundaries are no different from calls within a single program or |
258 | shared library. |
259 | |
260 | Member Function Pointer Call Checking |
261 | ===================================== |
262 | |
263 | This scheme checks that indirect calls via a member function pointer |
264 | take place using an object of the correct dynamic type. Specifically, we |
265 | check that the dynamic type of the member function referenced by the member |
266 | function pointer matches the "function pointer" part of the member function |
267 | pointer, and that the member function's class type is related to the base |
268 | type of the member function. This CFI scheme can be enabled on its own using |
269 | ``-fsanitize=cfi-mfcall``. |
270 | |
271 | The compiler will only emit a full CFI check if the member function pointer's |
272 | base type is complete. This is because the complete definition of the base |
273 | type contains information that is necessary to correctly compile the CFI |
274 | check. To ensure that the compiler always emits a full CFI check, it is |
275 | recommended to also pass the flag ``-fcomplete-member-pointers``, which |
276 | enables a non-conforming language extension that requires member pointer |
277 | base types to be complete if they may be used for a call. |
278 | |
279 | For this scheme to work, all translation units containing the definition |
280 | of a virtual member function (whether inline or not), other than members |
281 | of :ref:`blacklisted <cfi-blacklist>` types or types with public :doc:`LTO |
282 | visibility <LTOVisibility>`, must be compiled with ``-flto`` or ``-flto=thin`` |
283 | enabled and be statically linked into the program. |
284 | |
285 | This scheme is currently not compatible with cross-DSO CFI or the |
286 | Microsoft ABI. |
287 | |
288 | .. _cfi-blacklist: |
289 | |
290 | Blacklist |
291 | ========= |
292 | |
293 | A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain |
294 | source files, functions and types using the ``src``, ``fun`` and ``type`` |
295 | entity types. Specific CFI modes can be be specified using ``[section]`` |
296 | headers. |
297 | |
298 | .. code-block:: bash |
299 | |
300 | # Suppress all CFI checking for code in a file. |
301 | src:bad_file.cpp |
302 | src:bad_header.h |
303 | # Ignore all functions with names containing MyFooBar. |
304 | fun:*MyFooBar* |
305 | # Ignore all types in the standard library. |
306 | type:std::* |
307 | # Disable only unrelated cast checks for this function |
308 | [cfi-unrelated-cast] |
309 | fun:*UnrelatedCast* |
310 | # Disable CFI call checks for this function without affecting cast checks |
311 | [cfi-vcall|cfi-nvcall|cfi-icall] |
312 | fun:*BadCall* |
313 | |
314 | |
315 | .. _cfi-cross-dso: |
316 | |
317 | Shared library support |
318 | ====================== |
319 | |
320 | Use **-f[no-]sanitize-cfi-cross-dso** to enable the cross-DSO control |
321 | flow integrity mode, which allows all CFI schemes listed above to |
322 | apply across DSO boundaries. As in the regular CFI, each DSO must be |
323 | built with ``-flto``. |
324 | |
325 | Normally, CFI checks will only be performed for classes that have hidden LTO |
326 | visibility. With this flag enabled, the compiler will emit cross-DSO CFI |
327 | checks for all classes, except for those which appear in the CFI blacklist |
328 | or which use a ``no_sanitize`` attribute. |
329 | |
330 | Design |
331 | ====== |
332 | |
333 | Please refer to the :doc:`design document<ControlFlowIntegrityDesign>`. |
334 | |
335 | Publications |
336 | ============ |
337 | |
338 | `Control-Flow Integrity: Principles, Implementations, and Applications <https://research.microsoft.com/pubs/64250/ccs05.pdf>`_. |
339 | Martin Abadi, Mihai Budiu, Úlfar Erlingsson, Jay Ligatti. |
340 | |
341 | `Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM <http://www.pcc.me.uk/~peter/acad/usenix14.pdf>`_. |
342 | Caroline Tice, Tom Roeder, Peter Collingbourne, Stephen Checkoway, |
343 | Úlfar Erlingsson, Luis Lozano, Geoff Pike. |
344 | |