CVE-2026-72139

Source
https://cve.org/CVERecord?id=CVE-2026-72139
Import Source
https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-72139.json
JSON Data
https://api.osv.dev/v1/vulns/CVE-2026-72139
Downstream
Published
2026-08-15T05:53:13.279Z
Modified
2026-08-18T03:56:20.820695132Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
Summary
tcp: defer md5sig_info kfree past RCU grace period in tcp_connect
Details

In the Linux kernel, the following vulnerability has been resolved:

tcp: defer md5siginfo kfree past RCU grace period in tcpconnect

The md5+ao reconciliation in tcpconnect() (net/ipv4/tcpoutput.c) has two symmetric branches:

if (needs_md5) {
    tcp_ao_destroy_sock(sk, false);
} else if (needs_ao) {
    tcp_clear_md5_list(sk);
    kfree(rcu_replace_pointer(tp->md5sig_info, NULL, ...));
}

Both branches free a per-socket auth-info object while the socket is in TCPSYNSENT and is already on the inet ehash (inserted by inethashconnect() in tcpv4connect()). Both branches are reachable by softirq RX-path readers that load the corresponding info pointer via implicit RCU before bhlocksock_nested() is taken.

The needsmd5 branch is fixed in the prior patch by re-introducing the callrcu() free in tcpaodestroysock(): the equivalent per-key loop runs inside tcpaoinfofreercu(), the RCU callback, so by the time it frees each tcpaokey all softirq readers that captured the container have already completed rcuread_unlock().

The needsao branch is not symmetric in the same way. The container free can be deferred via kfreercu(md5sig, rcu) -- struct tcpmd5siginfo already has the required rcu member (include/net/tcp.h:1999-2002), and the rest of the tree already does this in the tcpmd5siginfoadd() rollback paths (net/ipv4/tcpipv4.c:1410, 1436). But the per-key teardown is done by tcpclearmd5list() in process context BEFORE the container's RCU grace period: it walks &md5sig->head and frees each tcpmd5sigkey with bare hlistdel + kfree. A concurrent softirq reader in __tcpmd5do_lookup() / _tcpmd5dolookupexact() (tcpipv4.c:1253, 1298) walks the same list via hlistforeachentryrcu() and races with that bare kfree on the keys themselves -- a per-key slab use-after-free of the same class as the TCP-AO bug, on the same race window.

Fix this in two halves:

  1. Convert the bare kfree() in tcpconnect() to kfreercu() so the md5siginfo container joins the rest of the md5sig lifecycle. The local-variable lift is mechanical and required because kfreercu() is a macro that expects an lvalue.

  2. Make tcpclearmd5list() RCU-safe by replacing hlistdel + kfree(key) with hlistdelrcu + kfreercu(key, rcu). struct tcpmd5sigkey already carries the rcu member (include/net/tcp.h:1995) and tcpmd5dodel() (net/ipv4/tcpipv4.c:1456) already uses kfreercu, so this restores the lifecycle invariant the rest of the file follows rather than introducing a one-off.

The other caller of tcpclearmd5list() is tcpmd5destructsock() (net/ipv4/tcp.c:412), which runs from the sock destructor when the socket is already unhashed and unreachable; the extra grace period there is unnecessary but harmless. Making the helper unconditionally RCU-safe is the cleaner contract.

The needsao branch is not reachable by the userns reproducer used to demonstrate the AO-side splat (the repro installs both keys but ends up in the needsmd5 branch because the connect peer matches the MD5 key, not the AO key); however the symmetric race exists and a maintainer touching this code should not have to think about which branch escapes RCU and which one does not.

[also credits to Qihang, who found that this races with tcp-diag]

Database specific
{
    "osv_generated_from": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/72xxx/CVE-2026-72139.json",
    "cna_assigner": "Linux"
}
References

Affected packages

Git / git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Affected ranges

Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
51e547e8c89c661f6fbede4a28b1d33b13625683
Fixed
33a1bee413628378fd036a4f2b17ba86b0bc560c
Fixed
da48b9bf1eb95a9cfd09d615ca58cfc2b03de369
Fixed
b74cd55038905d5e74c1de109ab78a30b2ea0e1f

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-72139.json"

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
6.18.0
Fixed
6.18.40
Type
ECOSYSTEM
Events
Introduced
6.19.0
Fixed
7.1.5

Database specific

source
"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-72139.json"