[llvm-dev] [CFI] Manually linking classes that have no inheritance link

Enes Göktaş via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 15 05:08:34 PDT 2017


Hi,

I would like to propose extending the Control-Flow Integrity (CFI)
mechanism in LLVM/Clang with a feature that allows users to explicitly link
classes that have no inheritance link. Usually, if one class is used at
locations in code where this class is not expected, this will create a CFI
error at runtime, assuming the application is built with CFI enabled.
However, in cases where the user has a complex code structure or design
that should allow this behavior, there is currently no solution but
disabling the CFI checks. Disabling the CFI checks is not a preferable
option when one wants to protect against memory corruption exploitation.

This feature prevents the CFI errors by expanding the valid vtable sets at
virtual callsites with vtables of classes specified in a sanitizer
blacklist file by the user. This allows keeping the CFI checks enabled.

When applying CFI to Firefox, I had to use this feature to solve the CFI
errors caused by XPCOM in Firefox. XPCOM is a fundamental technique in
Firefox and its design is so complex and intricate that changing XPCOM to
solve the CFI errors would be very difficult. XPCOM allows components to be
written in multiple languages and allows them being used from different
languages. For example, components implemented in JavaScript(JS) can be
used from C++ through their corresponding classes defined in C++. However,
it is worth mentioning that these classes are not implemented in C++ but in
JS. Behind the scenes, during runtime a generic proxy class is used for all
JS-component classes within the C++ code. This proxy class leads the
execution to the JS code.
When CFI is applied, the CFI checks at virtual callsites that have the type
of a JS-component class, fail, because at runtime the vtable of the generic
proxy class is used at these virtual callsites, while there is no
inheritance link between the JS-component and the generic proxy class.

With the following patches I was able to specify the links between these
classes such that during compilation the vtable of the generic proxy class
was added to the vtable sets at virtual callsites with the type of the
JS-component classes:
- https://reviews.llvm.org/D34233
- https://reviews.llvm.org/D34231

Without these patches, XPCOM would have to be significantly changed and
probably written from scratch. Simply making the JS-component classes a
descendant of the generic proxy class, or vice versa, is not an option,
because this would break the design. Making the generic proxy class a
descendant of the JS-component classes would result in a bad design in
which the proxy class inherits from tens of classes. Also the vtable of the
proxy class should overlay the structure of the JS-component vtables in a
very specific way. Making one a descendant of the other will break the
overlaying property.

Kind regards,
Enes
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170615/7a4368b6/attachment.html>


More information about the llvm-dev mailing list