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 be 29 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. Experimental support for 32 :ref:`cross-DSO control flow integrity <cfi-cross-dso>` exists that 33 does not have these requirements. This cross-DSO support has unstable 34 ABI at this time. 35 36 .. _gold plugin: http://llvm.org/docs/GoldPlugin.html 37 38 .. _cfi-schemes: 39 40 Available schemes 41 ================= 42 43 Available schemes are: 44 45 - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks 46 <cfi-strictness>`. 47 - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong 48 dynamic type. 49 - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another 50 unrelated type to the wrong dynamic type. 51 - ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of 52 the wrong dynamic type. 53 - ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the 54 wrong dynamic type. 55 - ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic 56 type. 57 58 You can use ``-fsanitize=cfi`` to enable all the schemes and use 59 ``-fno-sanitize`` flag to narrow down the set of schemes as desired. 60 For example, you can build your program with 61 ``-fsanitize=cfi -fno-sanitize=cfi-nvcall,cfi-icall`` 62 to use all schemes except for non-virtual member function call and indirect call 63 checking. 64 65 Remember that you have to provide ``-flto`` if at least one CFI scheme is 66 enabled. 67 68 Trapping and Diagnostics 69 ======================== 70 71 By default, CFI will abort the program immediately upon detecting a control 72 flow integrity violation. You can use the :ref:`-fno-sanitize-trap= 73 <controlling-code-generation>` flag to cause CFI to print a diagnostic 74 similar to the one below before the program aborts. 75 76 .. code-block:: console 77 78 bad-cast.cpp:109:7: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast (vtable address 0x000000425a50) 79 0x000000425a50: note: vtable is of type 'A' 80 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 81 ^ 82 83 If diagnostics are enabled, you can also configure CFI to continue program 84 execution instead of aborting by using the :ref:`-fsanitize-recover= 85 <controlling-code-generation>` flag. 86 87 Forward-Edge CFI for Virtual Calls 88 ================================== 89 90 This scheme checks that virtual calls take place using a vptr of the correct 91 dynamic type; that is, the dynamic type of the called object must be a 92 derived class of the static type of the object used to make the call. 93 This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``. 94 95 For this scheme to work, all translation units containing the definition 96 of a virtual member function (whether inline or not), other than members 97 of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with 98 ``-fsanitize=cfi-vcall`` enabled and be statically linked into the program. 99 100 Performance 101 ----------- 102 103 A performance overhead of less than 1% has been measured by running the 104 Dromaeo benchmark suite against an instrumented version of the Chromium 105 web browser. Another good performance benchmark for this mechanism is the 106 virtual-call-heavy SPEC 2006 xalancbmk. 107 108 Note that this scheme has not yet been optimized for binary size; an increase 109 of up to 15% has been observed for Chromium. 110 111 Bad Cast Checking 112 ================= 113 114 This scheme checks that pointer casts are made to an object of the correct 115 dynamic type; that is, the dynamic type of the object must be a derived class 116 of the pointee type of the cast. The checks are currently only introduced 117 where the class being casted to is a polymorphic class. 118 119 Bad casts are not in themselves control flow integrity violations, but they 120 can also create security vulnerabilities, and the implementation uses many 121 of the same mechanisms. 122 123 There are two types of bad cast that may be forbidden: bad casts 124 from a base class to a derived class (which can be checked with 125 ``-fsanitize=cfi-derived-cast``), and bad casts from a pointer of 126 type ``void*`` or another unrelated type (which can be checked with 127 ``-fsanitize=cfi-unrelated-cast``). 128 129 The difference between these two types of casts is that the first is defined 130 by the C++ standard to produce an undefined value, while the second is not 131 in itself undefined behavior (it is well defined to cast the pointer back 132 to its original type). 133 134 If a program as a matter of policy forbids the second type of cast, that 135 restriction can normally be enforced. However it may in some cases be necessary 136 for a function to perform a forbidden cast to conform with an external API 137 (e.g. the ``allocate`` member function of a standard library allocator). Such 138 functions may be :ref:`blacklisted <cfi-blacklist>`. 139 140 For this scheme to work, all translation units containing the definition 141 of a virtual member function (whether inline or not), other than members 142 of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with 143 ``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled 144 and be statically linked into the program. 145 146 Non-Virtual Member Function Call Checking 147 ========================================= 148 149 This scheme checks that non-virtual calls take place using an object of 150 the correct dynamic type; that is, the dynamic type of the called object 151 must be a derived class of the static type of the object used to make the 152 call. The checks are currently only introduced where the object is of a 153 polymorphic class type. This CFI scheme can be enabled on its own using 154 ``-fsanitize=cfi-nvcall``. 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, must be compiled with 159 ``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program. 160 161 .. _cfi-strictness: 162 163 Strictness 164 ---------- 165 166 If a class has a single non-virtual base and does not introduce or override 167 virtual member functions or fields other than an implicitly defined virtual 168 destructor, it will have the same layout and virtual function semantics as 169 its base. By default, casts to such classes are checked as if they were made 170 to the least derived such class. 171 172 Casting an instance of a base class to such a derived class is technically 173 undefined behavior, but it is a relatively common hack for introducing 174 member functions on class instances with specific properties that works under 175 most compilers and should not have security implications, so we allow it by 176 default. It can be disabled with ``-fsanitize=cfi-cast-strict``. 177 178 Indirect Function Call Checking 179 =============================== 180 181 This scheme checks that function calls take place using a function of the 182 correct dynamic type; that is, the dynamic type of the function must match 183 the static type used at the call. This CFI scheme can be enabled on its own 184 using ``-fsanitize=cfi-icall``. 185 186 For this scheme to work, each indirect function call in the program, other 187 than calls in :ref:`blacklisted <cfi-blacklist>` functions, must call a 188 function which was either compiled with ``-fsanitize=cfi-icall`` enabled, 189 or whose address was taken by a function in a translation unit compiled with 190 ``-fsanitize=cfi-icall``. 191 192 If a function in a translation unit compiled with ``-fsanitize=cfi-icall`` 193 takes the address of a function not compiled with ``-fsanitize=cfi-icall``, 194 that address may differ from the address taken by a function in a translation 195 unit not compiled with ``-fsanitize=cfi-icall``. This is technically a 196 violation of the C and C++ standards, but it should not affect most programs. 197 198 Each translation unit compiled with ``-fsanitize=cfi-icall`` must be 199 statically linked into the program or shared library, and calls across 200 shared library boundaries are handled as if the callee was not compiled with 201 ``-fsanitize=cfi-icall``. 202 203 This scheme is currently only supported on the x86 and x86_64 architectures. 204 205 ``-fsanitize=cfi-icall`` and ``-fsanitize=function`` 206 ---------------------------------------------------- 207 208 This tool is similar to ``-fsanitize=function`` in that both tools check 209 the types of function calls. However, the two tools occupy different points 210 on the design space; ``-fsanitize=function`` is a developer tool designed 211 to find bugs in local development builds, whereas ``-fsanitize=cfi-icall`` 212 is a security hardening mechanism designed to be deployed in release builds. 213 214 ``-fsanitize=function`` has a higher space and time overhead due to a more 215 complex type check at indirect call sites, as well as a need for run-time 216 type information (RTTI), which may make it unsuitable for deployment. Because 217 of the need for RTTI, ``-fsanitize=function`` can only be used with C++ 218 programs, whereas ``-fsanitize=cfi-icall`` can protect both C and C++ programs. 219 220 On the other hand, ``-fsanitize=function`` conforms more closely with the C++ 221 standard and user expectations around interaction with shared libraries; 222 the identity of function pointers is maintained, and calls across shared 223 library boundaries are no different from calls within a single program or 224 shared library. 225 226 .. _cfi-blacklist: 227 228 Blacklist 229 ========= 230 231 A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain 232 source files, functions and types using the ``src``, ``fun`` and ``type`` 233 entity types. 234 235 In addition, if a type has a ``uuid`` attribute and the blacklist contains 236 the type entry ``attr:uuid``, CFI checks are suppressed for that type. This 237 allows all COM types to be easily blacklisted, which is useful as COM types 238 are typically defined outside of the linked program. 239 240 .. code-block:: bash 241 242 # Suppress checking for code in a file. 243 src:bad_file.cpp 244 src:bad_header.h 245 # Ignore all functions with names containing MyFooBar. 246 fun:*MyFooBar* 247 # Ignore all types in the standard library. 248 type:std::* 249 # Ignore all types with a uuid attribute. 250 type:attr:uuid 251 252 .. _cfi-cross-dso: 253 254 Shared library support 255 ====================== 256 257 Use **-f[no-]sanitize-cfi-cross-dso** to enable the cross-DSO control 258 flow integrity mode, which allows all CFI schemes listed above to 259 apply across DSO boundaries. As in the regular CFI, each DSO must be 260 built with ``-flto``. 261 262 Design 263 ====== 264 265 Please refer to the :doc:`design document<ControlFlowIntegrityDesign>`. 266 267 Publications 268 ============ 269 270 `Control-Flow Integrity: Principles, Implementations, and Applications <http://research.microsoft.com/pubs/64250/ccs05.pdf>`_. 271 Martin Abadi, Mihai Budiu, lfar Erlingsson, Jay Ligatti. 272 273 `Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM <http://www.pcc.me.uk/~peter/acad/usenix14.pdf>`_. 274 Caroline Tice, Tom Roeder, Peter Collingbourne, Stephen Checkoway, 275 lfar Erlingsson, Luis Lozano, Geoff Pike. 276