Concurrent Ruby - `AtomicReference#update` livelocks when the stored value is `Float::NAN`
Published: June 19, 2026
SECURITY IDENTIFIERS
- CVE: CVE-2026-54904 (NVD)
- GHSA: GHSA-h8w8-99g7-qmvj
GEM
PATCHED VERSIONS
>= 1.3.7
DESCRIPTION
Summary
Concurrent::AtomicReference#update can enter a permanent busy retry
loop when the current value is Float::NAN.
The issue is caused by the interaction between:
AtomicReference#update, which retries untilcompare_and_set(old_value, new_value)succeeds.- Numeric
compare_and_set, which checksold == old_valuebefore attempting the underlying atomic swap. - Ruby NaN semantics, where
Float::NAN == Float::NANis alwaysfalse.
As a result, once an AtomicReference contains Float::NAN, calling
#update repeatedly evaluates the caller's block and never returns.
In services that store externally derived numeric values in an
AtomicReference, this can cause CPU exhaustion or permanent
request/job hangs.
Impact
This is an application-level denial of service issue. If an application
stores externally derived numeric data in a Concurrent::AtomicReference,
an attacker or faulty upstream data source may be able to cause the
stored value to become Float::NAN. Any later call to
AtomicReference#update on that reference will spin indefinitely,
repeatedly executing the update block and consuming CPU.
Credit
Pranjali Thakur - depthfirst (depthfirst.com)
RELATED
- https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54904
- https://rubygems.org/gems/concurrent-ruby/versions/1.3.7
- https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7
- https://advisories.gitlab.com/gem/concurrent-ruby/CVE-2026-54904
- https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-h8w8-99g7-qmvj
- https://github.com/advisories/GHSA-h8w8-99g7-qmvj
