| Name |
Last commit
|
Last Update |
|---|---|---|
| .. | ||
| algorithm | ||
| base | ||
| cleanup | ||
| container | ||
| copts | ||
| debugging | ||
| flags | ||
| functional | ||
| hash | ||
| memory | ||
| meta | ||
| numeric | ||
| profiling | ||
| random | ||
| status | ||
| strings | ||
| synchronization | ||
| time | ||
| types | ||
| utility | ||
| BUILD.bazel | ||
| CMakeLists.txt | ||
| abseil.podspec.gen.py |
Both Mutex and CondVar signal PerThreadSem/Waiter after satisfying the wait condition,
as the result the waiting thread may return w/o waiting on the
PerThreadSem/Waiter at all. If the waiting thread then exits, it currently
destroys Waiter object. As the result Waiter::Post can be called on
already destroyed object.
PerThreadSem/Waiter must be type-stable after creation and must not be destroyed.
The futex-based implementation is the only one that is not affected by the bug
since there is effectively nothing to destroy (maybe only UBSan/ASan
could complain about calling methods on a destroyed object).
Here is the problematic sequence of events:
1: void Mutex::Block(PerThreadSynch *s) {
2: while (s->state.load(std::memory_order_acquire) == PerThreadSynch::kQueued) {
3: if (!DecrementSynchSem(this, s, s->waitp->timeout)) {
4: PerThreadSynch *Mutex::Wakeup(PerThreadSynch *w) {
5: ...
6: w->state.store(PerThreadSynch::kAvailable, std::memory_order_release);
7: IncrementSynchSem(this, w);
8: ...
9: }
Consider line 6 is executed, then line 2 observes kAvailable and
line 3 is not called. The thread executing Mutex::Block returns from
the method, acquires the mutex, releases the mutex, exits and destroys
PerThreadSem/Waiter.
Now Mutex::Wakeup resumes and executes line 7 on the destroyed object. Boom!
CondVar uses a similar pattern.
Moreover the semaphore-based Waiter implementation is not even destruction-safe
(the Waiter cannot be used to signal own destruction). So even if Mutex/CondVar
would always pair Waiter::Post with Waiter::Wait before destroying PerThreadSem/Waiter,
it would still be subject to use-after-free bug on the semaphore.
PiperOrigin-RevId: 449159939
Change-Id: I497134fa8b6ce1294a422827c5f0de0e897cea31
| Name |
Last commit
|
Last Update |
|---|---|---|
| .. | ||
| algorithm | Loading commit data... | |
| base | Loading commit data... | |
| cleanup | Loading commit data... | |
| container | Loading commit data... | |
| copts | Loading commit data... | |
| debugging | Loading commit data... | |
| flags | Loading commit data... | |
| functional | Loading commit data... | |
| hash | Loading commit data... | |
| memory | Loading commit data... | |
| meta | Loading commit data... | |
| numeric | Loading commit data... | |
| profiling | Loading commit data... | |
| random | Loading commit data... | |
| status | Loading commit data... | |
| strings | Loading commit data... | |
| synchronization | Loading commit data... | |
| time | Loading commit data... | |
| types | Loading commit data... | |
| utility | Loading commit data... | |
| BUILD.bazel | Loading commit data... | |
| CMakeLists.txt | Loading commit data... | |
| abseil.podspec.gen.py | Loading commit data... |