xref: /aosp_15_r20/external/clang/docs/ControlFlowIntegrity.rst (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li======================
2*67e74705SXin LiControl Flow Integrity
3*67e74705SXin Li======================
4*67e74705SXin Li
5*67e74705SXin Li.. toctree::
6*67e74705SXin Li   :hidden:
7*67e74705SXin Li
8*67e74705SXin Li   ControlFlowIntegrityDesign
9*67e74705SXin Li
10*67e74705SXin Li.. contents::
11*67e74705SXin Li   :local:
12*67e74705SXin Li
13*67e74705SXin LiIntroduction
14*67e74705SXin Li============
15*67e74705SXin Li
16*67e74705SXin LiClang includes an implementation of a number of control flow integrity (CFI)
17*67e74705SXin Lischemes, which are designed to abort the program upon detecting certain forms
18*67e74705SXin Liof undefined behavior that can potentially allow attackers to subvert the
19*67e74705SXin Liprogram's control flow. These schemes have been optimized for performance,
20*67e74705SXin Liallowing developers to enable them in release builds.
21*67e74705SXin Li
22*67e74705SXin LiTo enable Clang's available CFI schemes, use the flag ``-fsanitize=cfi``.
23*67e74705SXin LiYou can also enable a subset of available :ref:`schemes <cfi-schemes>`.
24*67e74705SXin LiAs currently implemented, all schemes rely on link-time optimization (LTO);
25*67e74705SXin Liso it is required to specify ``-flto``, and the linker used must support LTO,
26*67e74705SXin Lifor example via the `gold plugin`_.
27*67e74705SXin Li
28*67e74705SXin LiTo allow the checks to be implemented efficiently, the program must
29*67e74705SXin Libe structured such that certain object files are compiled with CFI
30*67e74705SXin Lienabled, and are statically linked into the program. This may preclude
31*67e74705SXin Lithe use of shared libraries in some cases.
32*67e74705SXin Li
33*67e74705SXin LiThe compiler will only produce CFI checks for a class if it can infer hidden
34*67e74705SXin LiLTO visibility for that class. LTO visibility is a property of a class that
35*67e74705SXin Liis inferred from flags and attributes. For more details, see the documentation
36*67e74705SXin Lifor :doc:`LTO visibility <LTOVisibility>`.
37*67e74705SXin Li
38*67e74705SXin LiThe ``-fsanitize=cfi-{vcall,nvcall,derived-cast,unrelated-cast}`` flags
39*67e74705SXin Lirequire that a ``-fvisibility=`` flag also be specified. This is because the
40*67e74705SXin Lidefault visibility setting is ``-fvisibility=default``, which would disable
41*67e74705SXin LiCFI checks for classes without visibility attributes. Most users will want
42*67e74705SXin Lito specify ``-fvisibility=hidden``, which enables CFI checks for such classes.
43*67e74705SXin Li
44*67e74705SXin LiExperimental support for :ref:`cross-DSO control flow integrity
45*67e74705SXin Li<cfi-cross-dso>` exists that does not require classes to have hidden LTO
46*67e74705SXin Livisibility. This cross-DSO support has unstable ABI at this time.
47*67e74705SXin Li
48*67e74705SXin Li.. _gold plugin: http://llvm.org/docs/GoldPlugin.html
49*67e74705SXin Li
50*67e74705SXin Li.. _cfi-schemes:
51*67e74705SXin Li
52*67e74705SXin LiAvailable schemes
53*67e74705SXin Li=================
54*67e74705SXin Li
55*67e74705SXin LiAvailable schemes are:
56*67e74705SXin Li
57*67e74705SXin Li  -  ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks
58*67e74705SXin Li     <cfi-strictness>`.
59*67e74705SXin Li  -  ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong
60*67e74705SXin Li     dynamic type.
61*67e74705SXin Li  -  ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another
62*67e74705SXin Li     unrelated type to the wrong dynamic type.
63*67e74705SXin Li  -  ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of
64*67e74705SXin Li     the wrong dynamic type.
65*67e74705SXin Li  -  ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the
66*67e74705SXin Li     wrong dynamic type.
67*67e74705SXin Li  -  ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic
68*67e74705SXin Li     type.
69*67e74705SXin Li
70*67e74705SXin LiYou can use ``-fsanitize=cfi`` to enable all the schemes and use
71*67e74705SXin Li``-fno-sanitize`` flag to narrow down the set of schemes as desired.
72*67e74705SXin LiFor example, you can build your program with
73*67e74705SXin Li``-fsanitize=cfi -fno-sanitize=cfi-nvcall,cfi-icall``
74*67e74705SXin Lito use all schemes except for non-virtual member function call and indirect call
75*67e74705SXin Lichecking.
76*67e74705SXin Li
77*67e74705SXin LiRemember that you have to provide ``-flto`` if at least one CFI scheme is
78*67e74705SXin Lienabled.
79*67e74705SXin Li
80*67e74705SXin LiTrapping and Diagnostics
81*67e74705SXin Li========================
82*67e74705SXin Li
83*67e74705SXin LiBy default, CFI will abort the program immediately upon detecting a control
84*67e74705SXin Liflow integrity violation. You can use the :ref:`-fno-sanitize-trap=
85*67e74705SXin Li<controlling-code-generation>` flag to cause CFI to print a diagnostic
86*67e74705SXin Lisimilar to the one below before the program aborts.
87*67e74705SXin Li
88*67e74705SXin Li.. code-block:: console
89*67e74705SXin Li
90*67e74705SXin Li    bad-cast.cpp:109:7: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast (vtable address 0x000000425a50)
91*67e74705SXin Li    0x000000425a50: note: vtable is of type 'A'
92*67e74705SXin Li     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
93*67e74705SXin Li                  ^
94*67e74705SXin Li
95*67e74705SXin LiIf diagnostics are enabled, you can also configure CFI to continue program
96*67e74705SXin Liexecution instead of aborting by using the :ref:`-fsanitize-recover=
97*67e74705SXin Li<controlling-code-generation>` flag.
98*67e74705SXin Li
99*67e74705SXin LiForward-Edge CFI for Virtual Calls
100*67e74705SXin Li==================================
101*67e74705SXin Li
102*67e74705SXin LiThis scheme checks that virtual calls take place using a vptr of the correct
103*67e74705SXin Lidynamic type; that is, the dynamic type of the called object must be a
104*67e74705SXin Liderived class of the static type of the object used to make the call.
105*67e74705SXin LiThis CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``.
106*67e74705SXin Li
107*67e74705SXin LiFor this scheme to work, all translation units containing the definition
108*67e74705SXin Liof a virtual member function (whether inline or not), other than members
109*67e74705SXin Liof :ref:`blacklisted <cfi-blacklist>` types, must be compiled with
110*67e74705SXin Li``-fsanitize=cfi-vcall`` enabled and be statically linked into the program.
111*67e74705SXin Li
112*67e74705SXin LiPerformance
113*67e74705SXin Li-----------
114*67e74705SXin Li
115*67e74705SXin LiA performance overhead of less than 1% has been measured by running the
116*67e74705SXin LiDromaeo benchmark suite against an instrumented version of the Chromium
117*67e74705SXin Liweb browser. Another good performance benchmark for this mechanism is the
118*67e74705SXin Livirtual-call-heavy SPEC 2006 xalancbmk.
119*67e74705SXin Li
120*67e74705SXin LiNote that this scheme has not yet been optimized for binary size; an increase
121*67e74705SXin Liof up to 15% has been observed for Chromium.
122*67e74705SXin Li
123*67e74705SXin LiBad Cast Checking
124*67e74705SXin Li=================
125*67e74705SXin Li
126*67e74705SXin LiThis scheme checks that pointer casts are made to an object of the correct
127*67e74705SXin Lidynamic type; that is, the dynamic type of the object must be a derived class
128*67e74705SXin Liof the pointee type of the cast. The checks are currently only introduced
129*67e74705SXin Liwhere the class being casted to is a polymorphic class.
130*67e74705SXin Li
131*67e74705SXin LiBad casts are not in themselves control flow integrity violations, but they
132*67e74705SXin Lican also create security vulnerabilities, and the implementation uses many
133*67e74705SXin Liof the same mechanisms.
134*67e74705SXin Li
135*67e74705SXin LiThere are two types of bad cast that may be forbidden: bad casts
136*67e74705SXin Lifrom a base class to a derived class (which can be checked with
137*67e74705SXin Li``-fsanitize=cfi-derived-cast``), and bad casts from a pointer of
138*67e74705SXin Litype ``void*`` or another unrelated type (which can be checked with
139*67e74705SXin Li``-fsanitize=cfi-unrelated-cast``).
140*67e74705SXin Li
141*67e74705SXin LiThe difference between these two types of casts is that the first is defined
142*67e74705SXin Liby the C++ standard to produce an undefined value, while the second is not
143*67e74705SXin Liin itself undefined behavior (it is well defined to cast the pointer back
144*67e74705SXin Lito its original type) unless the object is uninitialized and the cast is a
145*67e74705SXin Li``static_cast`` (see C++14 [basic.life]p5).
146*67e74705SXin Li
147*67e74705SXin LiIf a program as a matter of policy forbids the second type of cast, that
148*67e74705SXin Lirestriction can normally be enforced. However it may in some cases be necessary
149*67e74705SXin Lifor a function to perform a forbidden cast to conform with an external API
150*67e74705SXin Li(e.g. the ``allocate`` member function of a standard library allocator). Such
151*67e74705SXin Lifunctions may be :ref:`blacklisted <cfi-blacklist>`.
152*67e74705SXin Li
153*67e74705SXin LiFor this scheme to work, all translation units containing the definition
154*67e74705SXin Liof a virtual member function (whether inline or not), other than members
155*67e74705SXin Liof :ref:`blacklisted <cfi-blacklist>` types, must be compiled with
156*67e74705SXin Li``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled
157*67e74705SXin Liand be statically linked into the program.
158*67e74705SXin Li
159*67e74705SXin LiNon-Virtual Member Function Call Checking
160*67e74705SXin Li=========================================
161*67e74705SXin Li
162*67e74705SXin LiThis scheme checks that non-virtual calls take place using an object of
163*67e74705SXin Lithe correct dynamic type; that is, the dynamic type of the called object
164*67e74705SXin Limust be a derived class of the static type of the object used to make the
165*67e74705SXin Licall. The checks are currently only introduced where the object is of a
166*67e74705SXin Lipolymorphic class type.  This CFI scheme can be enabled on its own using
167*67e74705SXin Li``-fsanitize=cfi-nvcall``.
168*67e74705SXin Li
169*67e74705SXin LiFor this scheme to work, all translation units containing the definition
170*67e74705SXin Liof a virtual member function (whether inline or not), other than members
171*67e74705SXin Liof :ref:`blacklisted <cfi-blacklist>` types, must be compiled with
172*67e74705SXin Li``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program.
173*67e74705SXin Li
174*67e74705SXin Li.. _cfi-strictness:
175*67e74705SXin Li
176*67e74705SXin LiStrictness
177*67e74705SXin Li----------
178*67e74705SXin Li
179*67e74705SXin LiIf a class has a single non-virtual base and does not introduce or override
180*67e74705SXin Livirtual member functions or fields other than an implicitly defined virtual
181*67e74705SXin Lidestructor, it will have the same layout and virtual function semantics as
182*67e74705SXin Liits base. By default, casts to such classes are checked as if they were made
183*67e74705SXin Lito the least derived such class.
184*67e74705SXin Li
185*67e74705SXin LiCasting an instance of a base class to such a derived class is technically
186*67e74705SXin Liundefined behavior, but it is a relatively common hack for introducing
187*67e74705SXin Limember functions on class instances with specific properties that works under
188*67e74705SXin Limost compilers and should not have security implications, so we allow it by
189*67e74705SXin Lidefault. It can be disabled with ``-fsanitize=cfi-cast-strict``.
190*67e74705SXin Li
191*67e74705SXin LiIndirect Function Call Checking
192*67e74705SXin Li===============================
193*67e74705SXin Li
194*67e74705SXin LiThis scheme checks that function calls take place using a function of the
195*67e74705SXin Licorrect dynamic type; that is, the dynamic type of the function must match
196*67e74705SXin Lithe static type used at the call. This CFI scheme can be enabled on its own
197*67e74705SXin Liusing ``-fsanitize=cfi-icall``.
198*67e74705SXin Li
199*67e74705SXin LiFor this scheme to work, each indirect function call in the program, other
200*67e74705SXin Lithan calls in :ref:`blacklisted <cfi-blacklist>` functions, must call a
201*67e74705SXin Lifunction which was either compiled with ``-fsanitize=cfi-icall`` enabled,
202*67e74705SXin Lior whose address was taken by a function in a translation unit compiled with
203*67e74705SXin Li``-fsanitize=cfi-icall``.
204*67e74705SXin Li
205*67e74705SXin LiIf a function in a translation unit compiled with ``-fsanitize=cfi-icall``
206*67e74705SXin Litakes the address of a function not compiled with ``-fsanitize=cfi-icall``,
207*67e74705SXin Lithat address may differ from the address taken by a function in a translation
208*67e74705SXin Liunit not compiled with ``-fsanitize=cfi-icall``. This is technically a
209*67e74705SXin Liviolation of the C and C++ standards, but it should not affect most programs.
210*67e74705SXin Li
211*67e74705SXin LiEach translation unit compiled with ``-fsanitize=cfi-icall`` must be
212*67e74705SXin Listatically linked into the program or shared library, and calls across
213*67e74705SXin Lishared library boundaries are handled as if the callee was not compiled with
214*67e74705SXin Li``-fsanitize=cfi-icall``.
215*67e74705SXin Li
216*67e74705SXin LiThis scheme is currently only supported on the x86 and x86_64 architectures.
217*67e74705SXin Li
218*67e74705SXin Li``-fsanitize=cfi-icall`` and ``-fsanitize=function``
219*67e74705SXin Li----------------------------------------------------
220*67e74705SXin Li
221*67e74705SXin LiThis tool is similar to ``-fsanitize=function`` in that both tools check
222*67e74705SXin Lithe types of function calls. However, the two tools occupy different points
223*67e74705SXin Lion the design space; ``-fsanitize=function`` is a developer tool designed
224*67e74705SXin Lito find bugs in local development builds, whereas ``-fsanitize=cfi-icall``
225*67e74705SXin Liis a security hardening mechanism designed to be deployed in release builds.
226*67e74705SXin Li
227*67e74705SXin Li``-fsanitize=function`` has a higher space and time overhead due to a more
228*67e74705SXin Licomplex type check at indirect call sites, as well as a need for run-time
229*67e74705SXin Litype information (RTTI), which may make it unsuitable for deployment. Because
230*67e74705SXin Liof the need for RTTI, ``-fsanitize=function`` can only be used with C++
231*67e74705SXin Liprograms, whereas ``-fsanitize=cfi-icall`` can protect both C and C++ programs.
232*67e74705SXin Li
233*67e74705SXin LiOn the other hand, ``-fsanitize=function`` conforms more closely with the C++
234*67e74705SXin Listandard and user expectations around interaction with shared libraries;
235*67e74705SXin Lithe identity of function pointers is maintained, and calls across shared
236*67e74705SXin Lilibrary boundaries are no different from calls within a single program or
237*67e74705SXin Lishared library.
238*67e74705SXin Li
239*67e74705SXin Li.. _cfi-blacklist:
240*67e74705SXin Li
241*67e74705SXin LiBlacklist
242*67e74705SXin Li=========
243*67e74705SXin Li
244*67e74705SXin LiA :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain
245*67e74705SXin Lisource files, functions and types using the ``src``, ``fun`` and ``type``
246*67e74705SXin Lientity types.
247*67e74705SXin Li
248*67e74705SXin Li.. code-block:: bash
249*67e74705SXin Li
250*67e74705SXin Li    # Suppress checking for code in a file.
251*67e74705SXin Li    src:bad_file.cpp
252*67e74705SXin Li    src:bad_header.h
253*67e74705SXin Li    # Ignore all functions with names containing MyFooBar.
254*67e74705SXin Li    fun:*MyFooBar*
255*67e74705SXin Li    # Ignore all types in the standard library.
256*67e74705SXin Li    type:std::*
257*67e74705SXin Li
258*67e74705SXin Li.. _cfi-cross-dso:
259*67e74705SXin Li
260*67e74705SXin LiShared library support
261*67e74705SXin Li======================
262*67e74705SXin Li
263*67e74705SXin LiUse **-f[no-]sanitize-cfi-cross-dso** to enable the cross-DSO control
264*67e74705SXin Liflow integrity mode, which allows all CFI schemes listed above to
265*67e74705SXin Liapply across DSO boundaries. As in the regular CFI, each DSO must be
266*67e74705SXin Libuilt with ``-flto``.
267*67e74705SXin Li
268*67e74705SXin LiNormally, CFI checks will only be performed for classes that have hidden LTO
269*67e74705SXin Livisibility. With this flag enabled, the compiler will emit cross-DSO CFI
270*67e74705SXin Lichecks for all classes, except for those which appear in the CFI blacklist
271*67e74705SXin Lior which use a ``no_sanitize`` attribute.
272*67e74705SXin Li
273*67e74705SXin LiDesign
274*67e74705SXin Li======
275*67e74705SXin Li
276*67e74705SXin LiPlease refer to the :doc:`design document<ControlFlowIntegrityDesign>`.
277*67e74705SXin Li
278*67e74705SXin LiPublications
279*67e74705SXin Li============
280*67e74705SXin Li
281*67e74705SXin Li`Control-Flow Integrity: Principles, Implementations, and Applications <http://research.microsoft.com/pubs/64250/ccs05.pdf>`_.
282*67e74705SXin LiMartin Abadi, Mihai Budiu, Úlfar Erlingsson, Jay Ligatti.
283*67e74705SXin Li
284*67e74705SXin Li`Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM <http://www.pcc.me.uk/~peter/acad/usenix14.pdf>`_.
285*67e74705SXin LiCaroline Tice, Tom Roeder, Peter Collingbourne, Stephen Checkoway,
286*67e74705SXin LiÚlfar Erlingsson, Luis Lozano, Geoff Pike.
287