This is an archive of the discontinued LLVM Phabricator instance.

[asan/win] Use SRW locks to fix a race in BlockingMutex
ClosedPublic

Authored by rnk on Jul 26 2018, 5:35 PM.

Details

Summary

Before my change, BlockingMutex used Windows critial sections. Critical
sections can only be initialized by calling InitializeCriticalSection,
dynamically.

The primary sanitizer allocator expects to be able to reinterpret zero
initialized memory as a BlockingMutex and immediately lock it.
RegionInfo contains a mutex, and it placement new is never called for
it. These objects are accessed via:

RegionInfo *GetRegionInfo(uptr class_id) const {
  DCHECK_LT(class_id, kNumClasses);
  RegionInfo *regions = reinterpret_cast<RegionInfo *>(SpaceEnd());
  return &regions[class_id];
}

The memory comes from the OS without any other initialization.

For various reasons described in the comments, BlockingMutex::Lock would
check if the object appeared to be zero-initialized, and it would lazily
call the LinkerInitialized constructor to initialize the critical
section. This pattern is obviously racy, and the code had a bunch of
FIXMEs about it.

The best fix here is to use slim reader writer locks, which can start
out zero-initialized. They are available starting in Windows Vista. I
think it's safe to go ahead and use them today.

Diff Detail

Repository
rL LLVM

Event Timeline

rnk created this revision.Jul 26 2018, 5:35 PM
rnk added a comment.Jul 27 2018, 4:23 PM

I'd like to try to get this in the next clang roll, since we're doing one for code coverage anyway. It'll help with https://crbug.com/783296#c57.

rnk added a comment.Jul 30 2018, 4:29 PM

@vitalybuka is OOO, so let's put this in and see how it goes.

This revision was not accepted when it landed; it landed in state Needs Review.Jul 30 2018, 4:32 PM
This revision was automatically updated to reflect the committed changes.