]> granicus.if.org Git - clang/commit
Implement CFI for indirect calls via a member function pointer.
authorPeter Collingbourne <peter@pcc.me.uk>
Tue, 26 Jun 2018 02:15:47 +0000 (02:15 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Tue, 26 Jun 2018 02:15:47 +0000 (02:15 +0000)
commit736ed08304d9589cdebf8eb54ef117931a217428
tree0fcfa64c89546250306df5bff1a31995e456d4a3
parent265fa9857ba66631d565c5292458b8bcbcedc401
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335569 91177308-0d34-0410-b5e6-96231b3b80d8
16 files changed:
docs/ControlFlowIntegrity.rst
docs/LTOVisibility.rst
include/clang/Basic/Sanitizers.def
lib/CodeGen/CGClass.cpp
lib/CodeGen/CGVTables.cpp
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/CodeGen/ItaniumCXXABI.cpp
lib/Driver/SanitizerArgs.cpp
lib/Driver/ToolChains/MSVC.cpp
test/CodeGenCXX/cfi-mfcall-incomplete.cpp [new file with mode: 0644]
test/CodeGenCXX/cfi-mfcall.cpp [new file with mode: 0644]
test/CodeGenCXX/type-metadata-memfun.cpp [new file with mode: 0644]
test/CodeGenCXX/type-metadata.cpp
test/Driver/fsanitize.c