summaryrefslogtreecommitdiffstats
path: root/clang/docs
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2015-03-14 02:42:25 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2015-03-14 02:42:25 +0000
commitd2926c91d5135a95912fdc142d133b647668e918 (patch)
tree671323e883dc8608d2382a0d9aa8e1d9858485ab /clang/docs
parent741c8f81e469930b7c72a59c82adae12c933b1e2 (diff)
downloadbcm5719-llvm-d2926c91d5135a95912fdc142d133b647668e918.tar.gz
bcm5719-llvm-d2926c91d5135a95912fdc142d133b647668e918.zip
Implement bad cast checks using control flow integrity information.
This scheme checks that pointer and lvalue 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. Differential Revision: http://reviews.llvm.org/D8312 llvm-svn: 232241
Diffstat (limited to 'clang/docs')
-rw-r--r--clang/docs/ControlFlowIntegrity.rst54
-rw-r--r--clang/docs/UsersManual.rst6
2 files changed, 60 insertions, 0 deletions
diff --git a/clang/docs/ControlFlowIntegrity.rst b/clang/docs/ControlFlowIntegrity.rst
index a4c60b3d98a..51c99177674 100644
--- a/clang/docs/ControlFlowIntegrity.rst
+++ b/clang/docs/ControlFlowIntegrity.rst
@@ -58,6 +58,60 @@ 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 blacklisted using a :doc:`SanitizerSpecialCaseList`.
+
+For this scheme to work, all translation units containing the definition
+of a virtual member function (whether inline or not) must be compiled with
+``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled
+and be statically linked into the program. Classes in the C++ standard library
+(under namespace ``std``) are exempted from checking, and therefore programs
+may be linked against a pre-built standard library, but this may change in
+the future.
+
+.. _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``.
+
Design
------
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index c02495b8d3d..bde3c4a08e9 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -968,6 +968,12 @@ are listed below.
``true`` nor ``false``.
- ``-fsanitize=bounds``: Out of bounds array indexing, in cases
where the array bound can be statically determined.
+ - ``-fsanitize=cfi-cast-strict``: Enables :ref:`strict cast checks
+ <cfi-strictness>`.
+ - ``-fsanitize=cfi-derived-cast``: Base-to-derived cast to the wrong
+ dynamic type. Implies ``-flto``.
+ - ``-fsanitize=cfi-unrelated-cast``: Cast from ``void*`` or another
+ unrelated type to the wrong dynamic type. Implies ``-flto``.
- ``-fsanitize=cfi-vptr``: Use of an object whose vptr is of the
wrong dynamic type. Implies ``-flto``.
- ``-fsanitize=enum``: Load of a value of an enumerated type which
OpenPOWER on IntegriCloud