This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Lock accesses to PathMappingLists's internals
ClosedPublic

Authored by bulbazord on Apr 14 2023, 2:24 PM.

Details

Summary

This class is not safe in multithreaded code. It's possible for one
thread to modify a PathMappingList's m_pair vector while another
thread is iterating over it, effectively invalidating the iterator and
potentially leading to crashes or other difficult-to-diagnose bugs.

rdar://107695786

Diff Detail

Event Timeline

bulbazord created this revision.Apr 14 2023, 2:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 14 2023, 2:24 PM
bulbazord requested review of this revision.Apr 14 2023, 2:24 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 14 2023, 2:24 PM

Does this actually have to be a recursive mutex?

Does this actually have to be a recursive mutex?

Good point, I don't think it does. I'll update this.

Does this actually have to be a recursive mutex?

Good point, I don't think it does. I'll update this.

Scratch that -- It unfortunately does need to be a recursive mutex. PathMappingList has a callback that may try to perform another operation on the list itself. This happens if you try to use target modules search-paths add -- We append to the list, the specified callback tries to read the size of the list. With a std::mutex we deadlock.

Does this actually have to be a recursive mutex?

Good point, I don't think it does. I'll update this.

Scratch that -- It unfortunately does need to be a recursive mutex. PathMappingList has a callback that may try to perform another operation on the list itself. This happens if you try to use target modules search-paths add -- We append to the list, the specified callback tries to read the size of the list. With a std::mutex we deadlock.

I see, and I assume it doesn't make sense to unlock the mutex before the callback?

This revision is now accepted and ready to land.Apr 14 2023, 3:50 PM

Does this actually have to be a recursive mutex?

Good point, I don't think it does. I'll update this.

Scratch that -- It unfortunately does need to be a recursive mutex. PathMappingList has a callback that may try to perform another operation on the list itself. This happens if you try to use target modules search-paths add -- We append to the list, the specified callback tries to read the size of the list. With a std::mutex we deadlock.

I see, and I assume it doesn't make sense to unlock the mutex before the callback?

I modified this patch locally to use std::mutex and release the mutex before invoking the callback. The test suite seems to like it, but it's still technically incorrect because of AppendUnique. Using std::mutex, we'd have to first lock the mutex, check to see if the given paths are already in m_pairs, and if they are not, unlock the mutex and call Append. If 2 things try to AppendUnique the same things at the same time and the stars align, they're going to Append the same thing twice (which is what happens without this patch anyway). We'd need to do some refactors if we wanted std::mutex to work correctly instead of std::recursive_mutex. That may be worth doing in the future, but I'm going to land this as-is for now.

This revision was automatically updated to reflect the committed changes.
nickdesaulniers added inline comments.
lldb/source/Target/PathMappingList.cpp
51
[412/1011] Building CXX object tools/lldb/sourc...CMakeFiles/lldbTarget.dir/PathMappingList.cpp.o
/android0/llvm-project/lldb/source/Target/PathMappingList.cpp:51:5: warning: 'scoped_lock' may not intend to support class template argument deduction [-Wctad-maybe-unsupported]
    std::scoped_lock locks(m_mutex, rhs.m_mutex);
    ^
/usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/mutex:692:11: note: add a deduction guide to suppress this warning
    class scoped_lock
          ^
72
/android0/llvm-project/lldb/source/Target/PathMappingList.cpp:72:3: warning: 'scoped_lock' may not intend to support class template argument deduction [-Wctad-maybe-unsupported]
  std::scoped_lock locks(m_mutex, rhs.m_mutex);
  ^
/usr/lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/mutex:692:11: note: add a deduction guide to suppress this warning
    class scoped_lock
          ^
bulbazord added inline comments.Apr 21 2023, 3:27 PM
lldb/source/Target/PathMappingList.cpp
72

Fixed in c5fc7809e05940674424aaed7dd06c6be0639864