This is an archive of the discontinued LLVM Phabricator instance.

Implementation and testing for poisoning vtable ptr in dtor.
ClosedPublic

Authored by nmusgrave on Sep 8 2015, 4:23 PM.

Details

Summary

After destruction, invocation of virtual functions prevented
by poisoning vtable pointer.

Diff Detail

Event Timeline

nmusgrave updated this revision to Diff 34277.Sep 8 2015, 4:23 PM
nmusgrave retitled this revision from to Implementation and testing for poisoning vtable ptr in dtor..
nmusgrave updated this object.
nmusgrave added reviewers: eugenis, kcc.
nmusgrave added a subscriber: cfe-commits.
eugenis added inline comments.Sep 8 2015, 5:00 PM
lib/CodeGen/CGClass.cpp
1687

You are poisoning the vtable pointer in the base destructor.
Isn't that too early?
For example, in the following case the vptr would be poisoned before ~A, right?
https://github.com/google/sanitizers/wiki/ThreadSanitizerPopularDataRaces#data-race-on-vptr

nmusgrave updated this revision to Diff 34357.Sep 9 2015, 12:09 PM
nmusgrave marked an inline comment as done.Sep 9 2015, 12:11 PM
eugenis added inline comments.Sep 9 2015, 12:42 PM
lib/CodeGen/CGClass.cpp
1697

Did you mean to move this chunk to the other cleanup class?
Is there a test that would fail if vptr is prematurely poisoned? There should be one (it's ok if it is only in compiler-rt, this could be hard to test with lit over IR).

nmusgrave updated this revision to Diff 34373.Sep 9 2015, 3:28 PM
  • Cleaned up impl.
nmusgrave marked an inline comment as done.Sep 9 2015, 4:09 PM
nmusgrave added inline comments.
lib/CodeGen/CGClass.cpp
1697

compiler-rt/test/msan/dtor-multiple-inheritance.cc checks that vtable is still accessible within dtors.

eugenis edited edge metadata.

So, this can not be moved to the complete destructor because that would fail to poisons vptrs of the base classes. On the other hand, the current implementation is a bit wasteful, as it can poison the same pointer multiple times when it is shared by the derived class and the first base.

Maybe skip poisoning if the first base (or whatever is at offset 0 in the record layout) is a dynamic class with non-trivial destructor?

lib/CodeGen/CGClass.cpp
1652

If it's a global function, it should have a more descriptive name, like EmitSanitizerDtorCallback.
OffsetPtr => just Ptr
And move the body of the function to this line to avoid unnecessary redeclaration.

test/CodeGenCXX/sanitize-dtor-derived-class.cpp
70

Check that this poisons exactly 8 bytes.

nmusgrave marked 2 inline comments as done.Sep 10 2015, 4:37 PM
nmusgrave added inline comments.
lib/CodeGen/CGClass.cpp
1652

It's inside of a namespace- is it still global?

eugenis added inline comments.Sep 10 2015, 4:39 PM
lib/CodeGen/CGClass.cpp
1652

In a sense. This namespace is not only about sanitizers, so Poison is ambiguous.

nmusgrave updated this revision to Diff 34614.Sep 11 2015, 6:27 PM
nmusgrave marked 2 inline comments as done.
nmusgrave edited edge metadata.
  • Fixed testing callback emission order to account for vptr.
nmusgrave updated this revision to Diff 34617.Sep 11 2015, 7:41 PM
  • Poison vtable in either complete or base dtor.
nmusgrave updated this revision to Diff 34822.Sep 15 2015, 11:53 AM
  • Re-checking testing for poisoning vtable.
nmusgrave updated this revision to Diff 34851.Sep 15 2015, 4:47 PM
  • Remove commented-out block.
eugenis accepted this revision.Sep 15 2015, 4:56 PM
eugenis edited edge metadata.

LGTM

This revision is now accepted and ready to land.Sep 15 2015, 4:56 PM
nmusgrave closed this revision.Sep 15 2015, 5:43 PM
chapuni added inline comments.
lib/CodeGen/CGClass.cpp
1756

It causes a warning in -Asserts. [-Wunused-private-field]