Look up another CVE · open CVE-2026-98070 in the interactive tracker
CVE-2026-98070
net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks()
Published 2026-09-25 (24 days ago) by the Linux kernel CNA. Subsystem net/rds. Debian urgency: not yet assigned.
What to do, per Debian release
Debian's own status for CVE-2026-98070 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | fixedDLA-4841-1 · 2026-10-17 · text | 6.1.190-1 | Update the kernel and reboot. DLA-4841-1 shipped the fix on 2026-10-17, in 6.1.190-1. A running kernel keeps the old code until the machine restarts. |
| Debian 13trixie | fixedDSA-6528-1 · 2026-09-29 · text | 6.12.111-1 | Update the kernel and reboot. DSA-6528-1 shipped the fix on 2026-09-29, in 6.12.111-1. A running kernel keeps the old code until the machine restarts. |
| Debian 14forky | fixed | 7.2.7-1 | Update the kernel and reboot. Fixed in 7.2.7-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.7-1 | Update the kernel and reboot. Fixed in 7.2.7-1. A running kernel keeps the old code until the machine restarts. |
| Debian 12bookworm · linux-6.12 | fixedDLA-4817-1 · 2026-10-04 · text | 6.12.111-1~deb12u1 | Update the kernel and reboot. DLA-4817-1 shipped the fix on 2026-10-04, in 6.12.111-1~deb12u1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
rds_tcp_reset_callbacks() quiesces the transmit path by setting the path state to RDS_CONN_RESETTING and then waiting for RDS_IN_XMIT to be sampled clear before swapping the underlying socket and calling rds_send_path_reset(). Sampling the bit clear is not the same as owning it: rds_send_xmit() can re-acquire RDS_IN_XMIT right after the wait_event() returns. Its state recheck after taking the lock is a store-buffering pattern (the resetter writes the state and reads the bit, the sender writes the bit and reads the state) and acquire_in_xmit() is only an acquire operation, so on weakly ordered architectures both sides can miss each other's write and the transmit path then runs concurrently with rds_send_path_reset() rewriting cp_xmit_* state - which is exactly what the comment above rds_send_path_reset() tells its callers to prevent. Take the lock instead, hold it across the socket swap and rds_send_path_reset(), and release it with a wake-up at the end. The lock-ordering constraint documented above the wait still holds: the lock is acquired before lock_sock(), so a sender inside tcp_sendmsg() can never be waited on while we hold the socket lock. Two details of the old code go away with the same change: - t_sock is now read only after the lock is acquired. The old code cached it before waiting; the teardown in rds_conn_shutdown() releases that socket and clears t_sock, so a pointer cached before the wait can be stale by the time the accept path resumes. Reading it under RDS_IN_XMIT is what makes the exclusion complete once the teardown owns the same lock, which the next patch arranges; until then the teardown still only samples the bit, and the two paths remain as exposed to each other as they are today. - The old !osock early path called rds_send_path_reset() with no serialization at all. It now runs under the lock like the normal path. The conditional RDS_CONN_RESETTING transition of the previous patch happens before the socket check either way: a path found without a socket is either still connecting (its reconnect worker blocked on t_conn_path_lock) and legitimately goes RESETTING -> UP on the new socket, or it has been torn down meanwhile and is dropped. The in-function comment describing the old wait-based quiesce is rewritten to describe the lock-based one, and the stale block comment above the function (which still described a return value and an incomplete list of t_sock writers) is refreshed to name all four writers - the connect, accept, teardown and swap paths - and what serializes each of them.
Where it lives
The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.
net/rds/tcp.c
- What this is
- RDS - RELIABLE DATAGRAM SOCKETSMAINTAINERS section matched on net/rds/ · netdev@vger.kernel.org · Supported
- Kernel module
- rds_tcp
Check it on the machine
grep -wE 'CONFIG_RDS|CONFIG_RDS_TCP' /boot/config-$(uname -r)Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.
lsmod | grep -w rds_tcpPrints a line if that module is loaded right now, and nothing if it is not. One that is not loaded can still be loaded later by anything that needs it.
Show whether Debian builds this, per release
Debian builds this as a loadable module. Every release below compiles it as a module on every flavour, so whether the code is in the running kernel depends on whether that module is loaded.
- bookworm, trixie, forky, sid, bookworm · linux-6.12m
- m
- a loadable module on every flavour - check lsmod, can be blacklisted
- Build switches
- CONFIG_RDS, CONFIG_RDS_TCP
- Reads as
- all on means the file is compiled; any one off means it is not.
From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages
Signals
- Published
- 2026-09-25 (24 days ago)source
- CVSS
- 8.1 high
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:Hsource recompute it - Attack vector
- network (AV:N)source
- EPSS
- 0.47%, higher than 39.6% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- not yet assignedsource
- Subsystem
- net/rds
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 4.7 | 5.10.271 | 670af4e4a4de |
| 4.7 | 5.15.222 | 830a2e21b200 |
| 4.7 | 6.1.189 | a05790cb4ff0 |
| 4.7 | 6.6.158 | d184e6dd4b8f |
| 4.7 | 6.12.111 | d625112564c3 |
| 4.7 | 6.18.53 | 8e4c3b7844c9 |
| 4.7 | 7.2.7 | 062d9e008c67 |
| 4.7 | 7.3 | 02c5f9dc2efd |
Debian advisories
| Advisory | Date | Shipped to | Debian |
|---|---|---|---|
| DLA-4841-1 | 2026-10-17 | bookworm 6.1.190-1 | tracker |
| DLA-4817-1 | 2026-10-04 | bookworm 6.12.111-1~deb12u1 | tracker |
| DSA-6528-1 | 2026-09-29 | trixie 6.12.111-1 | tracker |
Why the CNA scored it this way
Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source
- AV:NAttack vector, network
- rds_tcp_reset_callbacks() runs when a remote peer's TCP SYN to the RDS/TCP listener is accepted by rds_tcp_accept_one() while the local path already has t_sock set (the duelling-SYN case). The peer's routable TCP connection is what sets off the unsynchronized socket swap and rds_send_path_reset().
- AC:HAttack complexity, high
- The attacker must win a narrow store-buffering race between the resetter's test_bit(RDS_IN_XMIT) and rds_send_xmit()'s acquire_in_xmit()/state recheck, which only fails on weakly ordered CPUs. It also needs a duelling SYN that arrives while the local path is still CONNECTING, which the attacker cannot fully control.
- PR:NPrivileges required, none
- The RDS/TCP listener accepts incoming connections with no authentication. The accept path through rds_tcp_accept_one() into rds_tcp_reset_callbacks() needs only a reachable IP address and TCP port.
- UI:NUser interaction, none
- No local user action is needed. The reset path runs from the listen socket's data_ready callback and accept worker, and rds_send_xmit() is driven by the send worker or by pongs to peer pings.
- S:UScope, unchanged
- The corruption stays inside kernel memory under a single security authority. Crossing no VM or hardware isolation boundary.
- C:HConfidentiality impact, high
- rds_send_path_reset() puts cp_xmit_rm and zeroes the cp_xmit_* offsets while a concurrent rds_send_xmit() still dereferences that rds_message. This is a use-after-free, and a stale osock cached before the wait can be released twice. Reclaiming the freed object could leak kernel memory.
- I:HIntegrity impact, high
- The use-after-free of the rds_message and of the stale socket, plus the torn cp_xmit_* transmit state, corrupt kernel heap objects that could be reclaimed and used for controlled writes.
- A:HAvailability impact, high
- A sender using a freed cp_xmit_rm, or a double sock_release() of the stale osock, will oops or panic the kernel.