diff options
| author | 2016-09-03 22:46:54 +0000 | |
|---|---|---|
| committer | 2016-09-03 22:46:54 +0000 | |
| commit | b5500b9ca0102f1ccaf32f0e77e96d0739aded9b (patch) | |
| tree | e1b7ebb5a0231f9e6d8d3f6f719582cebd64dc98 /gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst | |
| parent | clarify purpose of src/gnu/ directory. (diff) | |
| download | wireguard-openbsd-b5500b9ca0102f1ccaf32f0e77e96d0739aded9b.tar.xz wireguard-openbsd-b5500b9ca0102f1ccaf32f0e77e96d0739aded9b.zip | |
Use the space freed up by sparc and zaurus to import LLVM.
ok hackroom@
Diffstat (limited to 'gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst')
| -rw-r--r-- | gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst b/gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst new file mode 100644 index 00000000000..780ff882d0e --- /dev/null +++ b/gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst @@ -0,0 +1,275 @@ +====================== +Control Flow Integrity +====================== + +.. toctree:: + :hidden: + + ControlFlowIntegrityDesign + +.. contents:: + :local: + +Introduction +============ + +Clang includes an implementation of a number of control flow integrity (CFI) +schemes, which are designed to abort the program upon detecting certain forms +of undefined behavior that can potentially allow attackers to subvert the +program's control flow. These schemes have been optimized for performance, +allowing developers to enable them in release builds. + +To enable Clang's available CFI schemes, use the flag ``-fsanitize=cfi``. +You can also enable a subset of available :ref:`schemes <cfi-schemes>`. +As currently implemented, all schemes rely on link-time optimization (LTO); +so it is required to specify ``-flto``, and the linker used must support LTO, +for example via the `gold plugin`_. + +To allow the checks to be implemented efficiently, the program must be +structured such that certain object files are compiled with CFI +enabled, and are statically linked into the program. This may preclude +the use of shared libraries in some cases. Experimental support for +:ref:`cross-DSO control flow integrity <cfi-cross-dso>` exists that +does not have these requirements. This cross-DSO support has unstable +ABI at this time. + +.. _gold plugin: http://llvm.org/docs/GoldPlugin.html + +.. _cfi-schemes: + +Available schemes +================= + +Available schemes are: + + - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks + <cfi-strictness>`. + - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong + dynamic type. + - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another + unrelated type to the wrong dynamic type. + - ``-fsanitize=cfi-nvcall``: Non-virtual call via an object whose vptr is of + the wrong dynamic type. + - ``-fsanitize=cfi-vcall``: Virtual call via an object whose vptr is of the + wrong dynamic type. + - ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic + type. + +You can use ``-fsanitize=cfi`` to enable all the schemes and use +``-fno-sanitize`` flag to narrow down the set of schemes as desired. +For example, you can build your program with +``-fsanitize=cfi -fno-sanitize=cfi-nvcall,cfi-icall`` +to use all schemes except for non-virtual member function call and indirect call +checking. + +Remember that you have to provide ``-flto`` if at least one CFI scheme is +enabled. + +Trapping and Diagnostics +======================== + +By default, CFI will abort the program immediately upon detecting a control +flow integrity violation. You can use the :ref:`-fno-sanitize-trap= +<controlling-code-generation>` flag to cause CFI to print a diagnostic +similar to the one below before the program aborts. + +.. code-block:: console + + bad-cast.cpp:109:7: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast (vtable address 0x000000425a50) + 0x000000425a50: note: vtable is of type 'A' + 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 + ^ + +If diagnostics are enabled, you can also configure CFI to continue program +execution instead of aborting by using the :ref:`-fsanitize-recover= +<controlling-code-generation>` flag. + +Forward-Edge CFI for Virtual Calls +================================== + +This scheme checks that virtual calls take place using a vptr of the correct +dynamic type; that is, the dynamic type of the called object must be a +derived class of the static type of the object used to make the call. +This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``. + +For this scheme to work, all translation units containing the definition +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with +``-fsanitize=cfi-vcall`` enabled and be statically linked into the program. + +Performance +----------- + +A performance overhead of less than 1% has been measured by running the +Dromaeo benchmark suite against an instrumented version of the Chromium +web browser. Another good performance benchmark for this mechanism is the +virtual-call-heavy SPEC 2006 xalancbmk. + +Note that this scheme has not yet been optimized for binary size; an increase +of up to 15% has been observed for Chromium. + +Bad Cast Checking +================= + +This scheme checks that pointer casts are made to an object of the correct +dynamic type; that is, the dynamic type of the object must be a derived class +of the pointee type of the cast. The checks are currently only introduced +where the class being casted to is a polymorphic class. + +Bad casts are not in themselves control flow integrity violations, but they +can also create security vulnerabilities, and the implementation uses many +of the same mechanisms. + +There are two types of bad cast that may be forbidden: bad casts +from a base class to a derived class (which can be checked with +``-fsanitize=cfi-derived-cast``), and bad casts from a pointer of +type ``void*`` or another unrelated type (which can be checked with +``-fsanitize=cfi-unrelated-cast``). + +The difference between these two types of casts is that the first is defined +by the C++ standard to produce an undefined value, while the second is not +in itself undefined behavior (it is well defined to cast the pointer back +to its original type). + +If a program as a matter of policy forbids the second type of cast, that +restriction can normally be enforced. However it may in some cases be necessary +for a function to perform a forbidden cast to conform with an external API +(e.g. the ``allocate`` member function of a standard library allocator). Such +functions may be :ref:`blacklisted <cfi-blacklist>`. + +For this scheme to work, all translation units containing the definition +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with +``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled +and be statically linked into the program. + +Non-Virtual Member Function Call Checking +========================================= + +This scheme checks that non-virtual calls take place using an object of +the correct dynamic type; that is, the dynamic type of the called object +must be a derived class of the static type of the object used to make the +call. The checks are currently only introduced where the object is of a +polymorphic class type. This CFI scheme can be enabled on its own using +``-fsanitize=cfi-nvcall``. + +For this scheme to work, all translation units containing the definition +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted <cfi-blacklist>` types, must be compiled with +``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program. + +.. _cfi-strictness: + +Strictness +---------- + +If a class has a single non-virtual base and does not introduce or override +virtual member functions or fields other than an implicitly defined virtual +destructor, it will have the same layout and virtual function semantics as +its base. By default, casts to such classes are checked as if they were made +to the least derived such class. + +Casting an instance of a base class to such a derived class is technically +undefined behavior, but it is a relatively common hack for introducing +member functions on class instances with specific properties that works under +most compilers and should not have security implications, so we allow it by +default. It can be disabled with ``-fsanitize=cfi-cast-strict``. + +Indirect Function Call Checking +=============================== + +This scheme checks that function calls take place using a function of the +correct dynamic type; that is, the dynamic type of the function must match +the static type used at the call. This CFI scheme can be enabled on its own +using ``-fsanitize=cfi-icall``. + +For this scheme to work, each indirect function call in the program, other +than calls in :ref:`blacklisted <cfi-blacklist>` functions, must call a +function which was either compiled with ``-fsanitize=cfi-icall`` enabled, +or whose address was taken by a function in a translation unit compiled with +``-fsanitize=cfi-icall``. + +If a function in a translation unit compiled with ``-fsanitize=cfi-icall`` +takes the address of a function not compiled with ``-fsanitize=cfi-icall``, +that address may differ from the address taken by a function in a translation +unit not compiled with ``-fsanitize=cfi-icall``. This is technically a +violation of the C and C++ standards, but it should not affect most programs. + +Each translation unit compiled with ``-fsanitize=cfi-icall`` must be +statically linked into the program or shared library, and calls across +shared library boundaries are handled as if the callee was not compiled with +``-fsanitize=cfi-icall``. + +This scheme is currently only supported on the x86 and x86_64 architectures. + +``-fsanitize=cfi-icall`` and ``-fsanitize=function`` +---------------------------------------------------- + +This tool is similar to ``-fsanitize=function`` in that both tools check +the types of function calls. However, the two tools occupy different points +on the design space; ``-fsanitize=function`` is a developer tool designed +to find bugs in local development builds, whereas ``-fsanitize=cfi-icall`` +is a security hardening mechanism designed to be deployed in release builds. + +``-fsanitize=function`` has a higher space and time overhead due to a more +complex type check at indirect call sites, as well as a need for run-time +type information (RTTI), which may make it unsuitable for deployment. Because +of the need for RTTI, ``-fsanitize=function`` can only be used with C++ +programs, whereas ``-fsanitize=cfi-icall`` can protect both C and C++ programs. + +On the other hand, ``-fsanitize=function`` conforms more closely with the C++ +standard and user expectations around interaction with shared libraries; +the identity of function pointers is maintained, and calls across shared +library boundaries are no different from calls within a single program or +shared library. + +.. _cfi-blacklist: + +Blacklist +========= + +A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain +source files, functions and types using the ``src``, ``fun`` and ``type`` +entity types. + +In addition, if a type has a ``uuid`` attribute and the blacklist contains +the type entry ``attr:uuid``, CFI checks are suppressed for that type. This +allows all COM types to be easily blacklisted, which is useful as COM types +are typically defined outside of the linked program. + +.. code-block:: bash + + # Suppress checking for code in a file. + src:bad_file.cpp + src:bad_header.h + # Ignore all functions with names containing MyFooBar. + fun:*MyFooBar* + # Ignore all types in the standard library. + type:std::* + # Ignore all types with a uuid attribute. + type:attr:uuid + +.. _cfi-cross-dso: + +Shared library support +====================== + +Use **-f[no-]sanitize-cfi-cross-dso** to enable the cross-DSO control +flow integrity mode, which allows all CFI schemes listed above to +apply across DSO boundaries. As in the regular CFI, each DSO must be +built with ``-flto``. + +Design +====== + +Please refer to the :doc:`design document<ControlFlowIntegrityDesign>`. + +Publications +============ + +`Control-Flow Integrity: Principles, Implementations, and Applications <http://research.microsoft.com/pubs/64250/ccs05.pdf>`_. +Martin Abadi, Mihai Budiu, Úlfar Erlingsson, Jay Ligatti. + +`Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM <http://www.pcc.me.uk/~peter/acad/usenix14.pdf>`_. +Caroline Tice, Tom Roeder, Peter Collingbourne, Stephen Checkoway, +Úlfar Erlingsson, Luis Lozano, Geoff Pike. |
