summaryrefslogtreecommitdiffstats
path: root/gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst
diff options
context:
space:
mode:
authorpascal <pascal@openbsd.org>2016-09-03 22:46:54 +0000
committerpascal <pascal@openbsd.org>2016-09-03 22:46:54 +0000
commitb5500b9ca0102f1ccaf32f0e77e96d0739aded9b (patch)
treee1b7ebb5a0231f9e6d8d3f6f719582cebd64dc98 /gnu/llvm/tools/clang/docs/ControlFlowIntegrity.rst
parentclarify purpose of src/gnu/ directory. (diff)
downloadwireguard-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.rst275
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.