You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
revise MicroLock not to access bytes outside of itself
Summary:
The `MicroLock` tests fail under libc++ with asan-abort `stack-buffer-overflow`.
Example:
```
SCARINESS: 32 (4-byte-read-stack-buffer-overflow)
#0 unsigned int std::__2::__cxx_atomic_load[abi:ue170004]<unsigned int>(std::__2::__cxx_atomic_base_impl<unsigned int> const*, std::__2::memory_order) libcxx/include/c++/v1/__atomic/cxx_atomic_impl.h:375
#1 std::__2::__atomic_base<unsigned int, false>::load[abi:ue170004](std::__2::memory_order) const libcxx/include/c++/v1/__atomic/atomic_base.h:60
facebook#2 folly::MicroLockBase<1000u, 0u>::try_lock() folly/MicroLock.h:319
facebook#3 SmallLocks_MicroLockTryLock_Test::TestBody() folly/synchronization/test/SmallLocksTest.cpp:314
```
The trouble is accessing the lock state as a 4-byte word, where the asan stack has allocated only 1 byte for the lock object - asan tracks this and aborts.
It is UB for `MicroLock` to perform atomic stores or atomic read-modify-write operations on the entire 4-byte aligned word containing the `MicroLock` which may be concurrent with other accesses to other bytes in the word. The 4-byte aligned word accesses are necessary in order to support using the `MicroLock` itself as a futex, on Linux platforms. The trouble is that Linux does not provide futex operations on all sizes of integer, only on 32-bit (4-byte) integers. If Linux were to provide futex operations on all sizes of integer, we would immediately switch to 8-bit (1-byte) integers here.
This diff fixes the UB and gets the tests passing under libc++ by switching to the `folly::ParkingLot`, as wrapped by `folly::atomic_notify_one` and `folly::atomic_wait` over `std::atomic<uint8_t>`, which indirects the 32-bit (4-byte) futex behind a sharded hashtable.
Alternatives are possible for getting the tests passing, although these alternatives would not fix the UB.
* We can disable sanitizers on even more functions, as well as switch to atomic builtins since the members of `std::atomic` are not marked as disabling the sanitizers.
* We can workaround just in the unit-tests by padding the on-stack `MicroLock` instances.
Reviewed By: praihan, ot, aary
Differential Revision: D76612658
fbshipit-source-id: 75e9f03e63c85c30c6201b9bce5cd303c9a2b530
0 commit comments