On 02/01/2013 12:42 AM, Caroline Tice wrote:
If this data could be emitted in a
declarative fashion, it might be possible to emit it by default, in a
separate ELF section. This way, it is always there when needed, and it
wouldn't have any performance impact if not used.
That might be possible; it would need to be carefully organized
though. If is not enough to have a list of all vtable addresses; we
need to know, for each virtual class (where by virtual class I mean a
class for which a vtable might be generated) the set of vtables that
is is legal for an object of that class to point to (i.e. for a base
class, it can point to its own vtable or to the vtable of any of its
descendants in the inheritance hierarchy).
At present, you emit calls to the __VLTRegisterPair() function to
implement the registration, correct? I wonder if it's possible to list
the arguments to the calls instead (possibly in such a way that no
relocations are needed). Initialization for verification mode would
pick up this data, performing the registration. Outside verification
mode, this data would just be ignored (and no ELF constructor needs to
be executed).
C++ virtual method calls are efficient, but they have
their problems. The vtable needs relocation (contributing to startup cost),
and we have the fragile base class problem (which severely constrains the
evolution of separately-compiled base classes). Assuming that we need the
vtable check and it has non-trivial cost, it might make sense to revamp C++
virtual method dispatch altogether, addressing both security and modularity
issues.
That might be best, but we don't have the authority to unilaterally
make a change of this magnitude to the standard. ;-)
This would only affect the cross-vendor C++ ABI, not the standard itself.
--
Florian Weimer / Red Hat Product Security Team