Skip to content

Commit a25814f

Browse files
authored
Merge pull request #1137 from jasnow/ghsa-syncbot-2026-06-21-12_42_28
GHSA/SYNC: 3 new concurrent-ruby gem advisories LGTM
2 parents d34daee + 80f3cbe commit a25814f

3 files changed

Lines changed: 159 additions & 0 deletions

File tree

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
gem: concurrent-ruby
3+
cve: 2026-54904
4+
ghsa: h8w8-99g7-qmvj
5+
url: https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54904
6+
title: Concurrent Ruby - `AtomicReference#update` livelocks when the
7+
stored value is `Float::NAN`
8+
date: 2026-06-19
9+
description: |
10+
### Summary
11+
12+
`Concurrent::AtomicReference#update` can enter a permanent busy retry
13+
loop when the current value is `Float::NAN`.
14+
15+
The issue is caused by the interaction between:
16+
- `AtomicReference#update`, which retries until `compare_and_set(old_value,
17+
new_value)` succeeds.
18+
- Numeric `compare_and_set`, which checks `old == old_value` before
19+
attempting the underlying atomic swap.
20+
- Ruby NaN semantics, where `Float::NAN == Float::NAN` is always `false`.
21+
22+
As a result, once an `AtomicReference` contains `Float::NAN`, calling
23+
`#update` repeatedly evaluates the caller's block and never returns.
24+
In services that store externally derived numeric values in an
25+
`AtomicReference`, this can cause CPU exhaustion or permanent
26+
request/job hangs.
27+
28+
### Impact
29+
30+
This is an application-level denial of service issue. If an application
31+
stores externally derived numeric data in a `Concurrent::AtomicReference`,
32+
an attacker or faulty upstream data source may be able to cause the
33+
stored value to become `Float::NAN`. Any later call to
34+
`AtomicReference#update` on that reference will spin indefinitely,
35+
repeatedly executing the update block and consuming CPU.
36+
37+
### Credit
38+
39+
Pranjali Thakur - depthfirst ([depthfirst.com](<http://depthfirst.com>))
40+
cvss_v4: 8.2
41+
patched_versions:
42+
- ">= 1.3.7"
43+
related:
44+
url:
45+
- https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54904
46+
- https://rubygems.org/gems/concurrent-ruby/versions/1.3.7
47+
- https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7
48+
- https://advisories.gitlab.com/gem/concurrent-ruby/CVE-2026-54904
49+
- https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-h8w8-99g7-qmvj
50+
- https://github.com/advisories/GHSA-h8w8-99g7-qmvj
51+
notes: |
52+
- cvss_v4 from GHSA
53+
- CVE is reserved, but not published.
54+
- Not on nvd.nist.gov so no cvss_v2 or cvss_v3.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
gem: concurrent-ruby
3+
cve: 2026-54905
4+
ghsa: wv3x-4vxv-whpp
5+
url: https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54905
6+
title: Concurrent Ruby - `ReentrantReadWriteLock` read-count overflow
7+
grants a write lock without exclusivity
8+
date: 2026-06-19
9+
description: |
10+
### Summary
11+
12+
`Concurrent::ReentrantReadWriteLock` can incorrectly grant a write lock
13+
after one thread acquires the read lock 32,768 times.
14+
15+
The lock stores a thread's local read and write hold counts in one
16+
integer. The low 15 bits are used for the read hold count, and bit 15
17+
is used as `WRITE_LOCK_HELD`. After 32,768 reentrant read acquisitions,
18+
the local read count crosses into the write-lock bit. `try_write_lock`
19+
then treats the thread as already holding a write lock and returns
20+
`true` without setting the global `RUNNING_WRITER` bit.
21+
22+
This breaks the core mutual-exclusion guarantee: the caller is told
23+
it has a write lock, but other threads can still hold or acquire
24+
read locks at the same time.
25+
26+
### Impact
27+
28+
This breaks the write-lock exclusivity guarantee. After the overflow,
29+
a thread can be told it has acquired the write lock while other threads
30+
can still hold or acquire read locks, allowing races and inconsistent
31+
reads of protected mutable state.
32+
33+
### Credit
34+
35+
Pranjali Thakur - depthfirst ([depthfirst.com](<http://depthfirst.com>))
36+
cvss_v4: 2.0
37+
patched_versions:
38+
- ">= 1.3.7"
39+
related:
40+
url:
41+
- https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54905
42+
- https://rubygems.org/gems/concurrent-ruby/versions/1.3.7
43+
- https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7
44+
- https://advisories.gitlab.com/gem/concurrent-ruby/CVE-2026-54905
45+
- https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-wv3x-4vxv-whpp
46+
- https://github.com/advisories/GHSA-wv3x-4vxv-whpp
47+
notes: |
48+
- cvss_v4 from GHSA
49+
- CVE is reserved, but not published.
50+
- Not on nvd.nist.gov so no cvss_v2 or cvss_v3.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
gem: concurrent-ruby
3+
cve: 2026-54906
4+
ghsa: 6wx8-w4f5-wwcr
5+
url: https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54906
6+
title: Concurrent Ruby - ReadWriteLock allows wrong-thread write
7+
release and stray read-release counter corruption
8+
date: 2026-06-19
9+
description: |
10+
### Summary
11+
12+
`Concurrent::ReadWriteLock#release_write_lock` does not verify that the
13+
calling thread acquired the write lock. Any thread with access to the
14+
lock object can release an active write lock held by another thread. A
15+
second writer can then enter its critical section while the first writer
16+
is still running.
17+
18+
`Concurrent::ReadWriteLock#release_read_lock` also decrements the shared
19+
counter even when no read lock is held. Calling it on a fresh lock
20+
changes the counter from `0` to `-1`, after which normal read acquisition
21+
raises `Concurrent::ResourceLimitError`.
22+
23+
This is a synchronization correctness issue in the public
24+
`Concurrent::ReadWriteLock` API. It should not be framed as an
25+
authorization bypass; the lock is an in-process concurrency primitive,
26+
not an access-control boundary.
27+
28+
### Impact
29+
30+
This can break the write-lock mutual exclusion guarantee and can also
31+
leave a lock unusable after a stray read release.
32+
The impact is local to applications that expose or misuse the manual
33+
`acquire_*` / `release_*` APIs. If the lock protects integrity-sensitive
34+
mutable state, wrong-thread write release can allow concurrent writers
35+
and data races. The stray read-release path can cause denial of service
36+
by corrupting the lock counter.
37+
38+
### Credit
39+
40+
Pranjali Thakur - depthfirst ([depthfirst.com](<http://depthfirst.com>))
41+
cvss_v4: 2.1
42+
patched_versions:
43+
- ">= 1.3.7"
44+
related:
45+
url:
46+
- https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54906
47+
- https://rubygems.org/gems/concurrent-ruby/versions/1.3.7
48+
- https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.3.7
49+
- https://advisories.gitlab.com/gem/concurrent-ruby/CVE-2026-54906
50+
- https://github.com/ruby-concurrency/concurrent-ruby/security/advisories/GHSA-6wx8-w4f5-wwcr
51+
- https://github.com/advisories/GHSA-6wx8-w4f5-wwcr
52+
notes: |
53+
- cvss_v4 from GHSA
54+
- CVE is reserved, but not published.
55+
- Not on nvd.nist.gov so no cvss_v2 or cvss_v3.

0 commit comments

Comments
 (0)