This is an archive of the discontinued LLVM Phabricator instance.

[tsan] Fix crash in objc_sync_enter/objc_sync_exit when using an Obj-C tagged pointer
ClosedPublic

Authored by kubamracek on Jul 23 2018, 4:48 PM.

Details

Summary

Objective-C tagged pointers (either bottom-most or top-most bit is 1) are valid Obj-C objects but are not valid pointers. Make sure we don't crash on them when used in objc_sync_enter/objc_sync_exit. Instead, let's synchronize on a global object.

Diff Detail

Event Timeline

kubamracek created this revision.Jul 23 2018, 4:48 PM
Herald added subscribers: Restricted Project, jfb. · View Herald TranscriptJul 23 2018, 4:48 PM
lib/tsan/rtl/tsan_interceptors_mac.cc
297

can we have a short docstring for both functions? Also, isTaggedObjCPointer?

299

return ((uptr)obj & kPossibleTaggedBits) != 0 ?

303

what's the point of taking in the argument then?

324

can we extract this line into a function with a name explaining it's semantics?

kubamracek added inline comments.Jul 23 2018, 5:08 PM
lib/tsan/rtl/tsan_interceptors_mac.cc
303

The point is that, ideally, the function would return a different sync address for different pointers. But for now, the implementation trivially returns the same address for all, which can cause false negatives.

kubamracek added inline comments.
lib/tsan/rtl/tsan_interceptors_mac.cc
297

Also, isTaggedObjCPointer?

In (almost) all of TSan, private functions starts with an uppercase letter. Let's not try to change style with this patch.

lib/tsan/rtl/tsan_interceptors_mac.cc
299

also all the helper functions should be static

george.karpenkov accepted this revision.Jul 23 2018, 5:20 PM
This revision is now accepted and ready to land.Jul 23 2018, 5:20 PM
dvyukov accepted this revision.Jul 24 2018, 12:49 AM
delcypher accepted this revision.Jul 24 2018, 8:26 AM

Other than minor suggestions the basic idea seems okay for now.

lib/tsan/rtl/tsan_interceptors_mac.cc
299

Perhaps the name should be IsTaggedObjCPointer?

308

There probably should be a TODO(kubamracek) or FIXME in here.

Do we even want to do Acquire() and Release() for tagged pointers? Even if we had a perfect implementation of SyncAddressForTaggedPointer() that still seems wrong because we could have two independent instances of a tagged pointer
(e.g. create two separate NSString with same value) and those shouldn't really be considered as the same object, but they would
be considered the same because their tagged pointer value is the same.

kubamracek added inline comments.Jul 24 2018, 9:00 AM
lib/tsan/rtl/tsan_interceptors_mac.cc
308

Yes, the entire idea of using value types (strings, integeres, timestamps) as synchronization objects is weird and most likely not what you intended anyway. Therefore this patch is really just to avoid crashing and to mirror what libobjc is actually doing when using @synchronize on a tagged pointer (it does actually establish synchronization if the pointer bits are exactly the same).

This revision was automatically updated to reflect the committed changes.
This revision was automatically updated to reflect the committed changes.

Thanks for the fast review!