diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2018-06-26 02:15:47 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2018-06-26 02:15:47 +0000 |
commit | e44acadf6ab0ec228dcba2e02b495c1dfe7338dd (patch) | |
tree | 9bee8e35f720ae18caf51815d1b2f0a1afffa08e /clang/docs/ControlFlowIntegrity.rst | |
parent | 689e363ff2294f43d2ee35d08777f7a7ea0ce7dd (diff) | |
download | bcm5719-llvm-e44acadf6ab0ec228dcba2e02b495c1dfe7338dd.tar.gz bcm5719-llvm-e44acadf6ab0ec228dcba2e02b495c1dfe7338dd.zip |
Implement CFI for indirect calls via a member function pointer.
Similarly to CFI on virtual and indirect calls, this implementation
tries to use program type information to make the checks as precise
as possible. The basic way that it works is as follows, where `C`
is the name of the class being defined or the target of a call and
the function type is assumed to be `void()`.
For virtual calls:
- Attach type metadata to the addresses of function pointers in vtables
(not the functions themselves) of type `void (B::*)()` for each `B`
that is a recursive dynamic base class of `C`, including `C` itself.
This type metadata has an annotation that the type is for virtual
calls (to distinguish it from the non-virtual case).
- At the call site, check that the computed address of the function
pointer in the vtable has type `void (C::*)()`.
For non-virtual calls:
- Attach type metadata to each non-virtual member function whose address
can be taken with a member function pointer. The type of a function
in class `C` of type `void()` is each of the types `void (B::*)()`
where `B` is a most-base class of `C`. A most-base class of `C`
is defined as a recursive base class of `C`, including `C` itself,
that does not have any bases.
- At the call site, check that the function pointer has one of the types
`void (B::*)()` where `B` is a most-base class of `C`.
Differential Revision: https://reviews.llvm.org/D47567
llvm-svn: 335569
Diffstat (limited to 'clang/docs/ControlFlowIntegrity.rst')
-rw-r--r-- | clang/docs/ControlFlowIntegrity.rst | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/clang/docs/ControlFlowIntegrity.rst b/clang/docs/ControlFlowIntegrity.rst index 6b397befdd9..fcc64098889 100644 --- a/clang/docs/ControlFlowIntegrity.rst +++ b/clang/docs/ControlFlowIntegrity.rst @@ -66,6 +66,8 @@ Available schemes are: wrong dynamic type. - ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic type. + - ``-fsanitize=cfi-mfcall``: Indirect call via a member function pointer 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. @@ -255,6 +257,34 @@ 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. +Member Function Pointer Call Checking +===================================== + +This scheme checks that indirect calls via a member function pointer +take place using an object of the correct dynamic type. Specifically, we +check that the dynamic type of the member function referenced by the member +function pointer matches the "function pointer" part of the member function +pointer, and that the member function's class type is related to the base +type of the member function. This CFI scheme can be enabled on its own using +``-fsanitize=cfi-mfcall``. + +The compiler will only emit a full CFI check if the member function pointer's +base type is complete. This is because the complete definition of the base +type contains information that is necessary to correctly compile the CFI +check. To ensure that the compiler always emits a full CFI check, it is +recommended to also pass the flag ``-fcomplete-member-pointers``, which +enables a non-conforming language extension that requires member pointer +base types to be complete if they may be used for a call. + +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 or types with public :doc:`LTO +visibility <LTOVisibility>`, must be compiled with ``-flto`` or ``-flto=thin`` +enabled and be statically linked into the program. + +This scheme is currently not compatible with cross-DSO CFI or the +Microsoft ABI. + .. _cfi-blacklist: Blacklist |