This is an archive of the discontinued LLVM Phabricator instance.

SmallVector: fix use-after-poison MSAN error in destructor
ClosedPublic

Authored by elsteveogrande on Jan 10 2018, 1:31 PM.

Details

Summary

Addresses issue: https://bugs.llvm.org/show_bug.cgi?id=34595

The topmost class, SmallVector, has internal storage for some elements; N - 1 elements' bytes worth of space. Meanwhile a base class SmallVectorTemplateCommon has room for one element as well, totaling N elements' worth of space.

The space for the N elements is contiguous and straddles SmallVectorTemplateCommon and SmallVector.

A class "between" those two owning the storage, SmallVectorImpl, in its destructor, calls the destructor for elements contained in the vector, if any. It uses destroy_range(begin, end) and deletes all items in sequence, starting from the end.

By the time the destructor for SmallVectorImpl is running, though, the memory for elements [1, N) is already poisoned, due to SmallVector's destructor having done its thing already.

So if the element type T has a nontrivial destructor that accesses any members of the T instance being destroyed, we'll run into a user-after-poison bug.

This patch moves the destruction loop into SmallVector's destructor, so any memory being accessed while dtors are running is not yet poisoned.

Confirmed this broke before (and now works with this patch) with these compiler flags:

-fsanitize=memory
-fsanitize-memory-use-after-dtor
-fsanitize-memory-track-origins

and with the cmake flag -DLLVM_USE_SANITIZER='MemoryWithOrigins;Undefined' as well as MSAN_OPTIONS=poison_in_dtor=1.

Diff Detail

Repository
rL LLVM

Event Timeline

elsteveogrande created this revision.Jan 10 2018, 1:31 PM
elsteveogrande set the repository for this revision to rL LLVM.
elsteveogrande edited the summary of this revision. (Show Details)Jan 10 2018, 1:36 PM

LGTM for fixing the use-after-dtor. I'll let @dblaikie comment since he brought up template bloat issues on https://reviews.llvm.org/D12970.

dblaikie accepted this revision.Jan 10 2018, 2:55 PM

Thanks for CCing me Matt - but yeah, this seems reasonable/makes sense to me!

This revision is now accepted and ready to land.Jan 10 2018, 2:55 PM
eugenis accepted this revision.Jan 10 2018, 2:57 PM

Thanks all! Seems I'm unable to land this.

I was working off the github clone (which I think is readonly). I then changed the remote URL to https://git.llvm.org/git/llvm.git/ and tried git svn dcommit, but it hangs there seemingly forever.

Any tricks to pushing this, or would someone else (with privileges?) be able to merge this?

Thanks! :)

This revision was automatically updated to reflect the committed changes.

Steve, you need commit access. See https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access. I've pushed this patch for you.