ubsan: check type_info equality via strcmp
Stephan Bergmann
sbergman at redhat.com
Tue Aug 20 06:45:47 PDT 2013
On 08/16/2013 08:26 PM, Richard Smith wrote:
> On Fri, Aug 16, 2013 at 2:38 AM, Stephan Bergmann <sbergman at redhat.com
> <mailto:sbergman at redhat.com>> wrote:
>
> I was trying out -fsanitizer=undefined on the LibreOffice code base
> (with a recent Clang trunk build), and ran into false positives
> claiming member calls were made on base class subobjects of wrong type.
>
> Turns out LibreOffice is somewhat over-eager with
> -fvisibility=hidden, leading to some classes that are used across
> multiple dynamic libraries nevertheless having their RTTI name
> symbols bound locally per library. While that is in violation of the
> Itanium ABI, it at least works with recent libstdc++ (which resorts
> to strcmp rather than pointer comparison these days, see [1])---and
> wouldn't normally get noticed anyway as there should not be uses of
> dynamic_cast involving those classes in the LibreOffice code base.
>
>
> I would much prefer for this to be first resolved in the Itanium ABI.
> The fix you suggest below will hide real problems in code that uses
> libc++ (where type_info comparison directly compares the __type_name
> fields).
>
> Also, it seems to me that you've found a real LibreOffice bug, if
> they're hiding the type information for exported types, and I don't want
> to weaken a sanitizer because it found a real bug.
I'm not sure it is that clear cut. For one, it is arguably beneficial
for LibreOffice to reduce the number of runtime (data) relocations by
"illegally" reducing classes to hidden visibility that are used across
multiple DSOs but for which it is known that their RTTI is not used (the
classes in question are special in that they are analogous to Java
interfaces, have only pure virtual member functions and no data members,
so no harm results from reducing their visibility in practice). (But I
could of course solve my original problem on the LibreOffice side
instead of the ubsan side, by making those classes non-hidden in builds
that use -fsanitizer=undefined.)
For another, the real problems that would be hidden by my suggested fix
would necessarily involve ODR violations, right? (In the sense that two
DSOs would contain non-exported classes with equal identifiers that are,
or should be considered, different.)
> From a more abstract POV, I think libstdc++ may have been misguided in
> trying to make the RTLD_LOCAL case "work". For instance, if I load two
> versions of the same DSO into my binary using RTLD_LOCAL, and use their
> type_info*s as keys in some container type (say, in a serialization
> library), there is no way to avoid a broken program. Perhaps it would
> have been better for them to admit that types with the same name from
> two different RTLD_LOCAL DSOs are different, just like every other entity.
I'm not sure I understand in how far you consider your example program
broken. If the container uses type_info* keys and pointer equality on
them, what will happen is that there can be different elements for which
key1->operator==(*key2) is true. But that is just in line with the C++
Standard.
Stephan
More information about the cfe-commits
mailing list