Make futex functions free functions instead of members
Summary:
The current futex API required a reference to a futex object in order to
invoke `futexWake()`, although this is not buggy by itself, it is technically
UB and nothing is stopping ASAN from catching this sort of use-after-free and
reporting it as an error. Especially when the futex is represented as a
pointer, requiring a dereference to reach a member function
The bug can come up when you call `futexWake()` on a futex that has been
destroyed, for example
```
auto&& futex_ptr = std::atomic<Futex<>*>{nullptr};
auto&& thread = std::thread{[&]() {
auto&& futex = Futex<>{0};
futex_ptr.store(&futex);
while (futex.load(std::memory_order_relaxed) != 1) {
futex.futexWait(0);
}
}};
while (!futex_ptr.load()) {}
futex_ptr.load()->store(1);
futex_ptr.load()->futexWake(1);
thread.join();
```
Here immediately after the `store(1)`, our thread could have loaded the value,
seen that it had changed, and never went to sleep. Or it could have seen the
value as 0, went to sleep and immediately returned when it saw that the value
in the futex word was not what was expected.
In the scenario described above calling `futexWake()` is done on a "dangling"
pointer. To avoid this, we just never dereference the pointer, and pass the
pointer to the futex syscall, where it will do the right things
A side benefit to the refactor is that adding specializations is very easy.
And we don't have to mess with member function specializations anymore, which
are inherently hard to work with (eg. cannot partially specialize)
The ADL extension points (currently implemented for `Futex<std::atomic>`,
`Futex<DeterministicAtomic>` and `Futex<EmulatedFutexAtomic>`) are
```
int futexWakeImpl(FutexType* futex, int count, uint32_t wakeMask);
FutexResult futexWaitImpl(
FutexType* futex,
uint32_t expected,
std::chrono::system_clock::time_point const* absSystemTime,
std::chrono::steady_clock::time_point const* absSteadyTime,
uint32_t waitMask);
```
Reviewed By: yfeldblum
Differential Revision: D9376527
fbshipit-source-id: bb2b54e511fdf1da992c630a9bc7dc37f76da641
Showing
folly/detail/Futex-inl.h
0 → 100644
Please register or sign in to comment