https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99537
Bug ID: 99537 Summary: Wrong memory_order used in stop_token ref-counting Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: lewissbaker.opensource at gmail dot com Target Milestone: --- In the implementation of stop_token the _Stop_state_t implements reference-counting for tracking shared ownership of the stop-state. This is done via two methods: void _M_add_owner() noexcept { _M_owners.fetch_add(1, memory_order::relaxed); } void _M_release_ownership() noexcept { if (_M_owners.fetch_sub(1, memory_order::release) == 1) delete this; } Other than initialising the _M_owners atomic value to 1, these are the only two accesses of the _M_owners variable. The 'fetch_sub()' operation in _M_release_ownership() should be using memory_order::acq_rel instead of memory_order::release. The use of 'release' only is insufficient as it does not synchronise with any corresponding 'acquire' operation. With the current implementation, it's possible that a prior write to one of the _M_value or _M_head data-members by a thread releasing the second-to-last reference might not be visible to another thread that releases the last reference and frees the memory, resulting in potential write to freed memory.