CVE-2025-39682 — Linux Kernel Improper Check for Unusual or Exceptional Conditions Vulnerability

CVE-2025-39682

Linux Kernel kTLS - Use-After-Free in tls_sw_recvmsg via Zero-Length Records on rx_list

What is Kernel TLS?

Kernel TLS (kTLS) moves TLS record encryption and decryption out of userspace libraries and into the Linux kernel. An application completes the TLS handshake normally in userspace, then hands the negotiated keys to the kernel with a setsockopt(SOL_TLS, TLS_TX/TLS_RX) call. From that point the socket carries plaintext to the application while the kernel does the record framing and crypto, which allows zero-copy paths such as sendfile() and splice() to work on TLS connections and lets NIC crypto offload take over where hardware supports it.

That makes kTLS attractive for anything that moves bulk data over TLS: nginx and other reverse proxies built with kTLS support, content delivery nodes, Kafka and database frontends, and NFS-over-TLS. It also means the code in net/tls/tls_sw.c parses attacker-influenced record streams inside the kernel, where a memory-safety bug becomes a kernel compromise rather than a crashed process.

Overview

CVE-2025-39682 is a use-after-free in the kTLS receive path, reachable through the ordinary recvmsg() and splice() interfaces on a socket that has kTLS receive enabled. The kernel keeps a list, rx_list, of records that have been decrypted but not yet delivered, because with TLS 1.3 the record type is not known until after decryption. Each recvmsg() call is supposed to return either a run of contiguous application-data records or a single non-data record, so when the record type changes the processing loop is meant to stop.

The check that stops the loop was written against the wrong variable. The corner case missed was a zero-length record arriving first from rx_list: because nothing had been copied yet, the loop continued and queued a record that was being handled in zero-copy mode. Queuing a zero-copy anchor to rx_list while the underlying TCP socket buffer is released leaves the anchor's fragment list pointing at freed pages.

Severity ratings disagree. NVD scores it 9.8 CRITICAL with a network attack vector, while STAR Labs and the distributions score it 7.1 and treat it as local privilege escalation. Both readings have a basis: a malicious TLS peer supplies the record sequence that sets up the free, but turning that into privilege escalation requires local syscalls on the target. Treat it as critical wherever kTLS receive is enabled on internet-facing sockets.

Affected Versions

Product Vulnerable Fixed
Linux kernel 6.1.y 6.0 through 6.1.148 6.1.149
Linux kernel 6.6.y 6.2 through 6.6.102 6.6.103
Linux kernel 6.12.y 6.7 through 6.12.43 6.12.44
Linux kernel 6.16.y 6.13 through 6.16.3 6.16.4
Linux kernel mainline 6.17-rc1, 6.17-rc2 6.17-rc3
Ubuntu 24.04 LTS linux before 6.8.0-86.87 6.8.0-86.87
Ubuntu 25.04 linux before 6.14.0-34.34 6.14.0-34.34

The flawed check was introduced in 6.0 by commit 84c61fe1a75b, so every stable series from 6.0 onward is affected until patched. Systems that never enable kTLS receive are not reachable through this path.

Technical Details

CWE-754, improper check for unusual or exceptional conditions: the code tests a condition that is almost always equivalent to the one it means to test, and the gap between them is the bug. In tls_sw_recvmsg() the early-exit test used copied && where it needed control &&. copied counts bytes handed to userspace; control records whether a record type has already been committed for this call. A zero-length record increments neither, so with the wrong variable the loop kept going instead of breaking on the type change.

The resulting sequence is two syscalls. First a read that presents an application-data record followed by a zero-length handshake record, which leaves the zero-length record queued on rx_list harmlessly. Then a recvmsg() that pulls a zero-copy record delivered through splice: the kernel queues the zero-copy anchor skb to rx_list while tls_rx_rec_done() releases the TCP skb behind it, so the anchor's frag_list holds a dangling page pointer. The socket close path, tls_sw_release_resources_rx(), then walks freed memory.

No authentication is required, complexity is low, and the trigger is a short deterministic sequence rather than a race that must be won. Published analysis carries it from the dangling page to root: isolate the page with splice, reclaim it through the buddy allocator using pipe writes, spray page-table pages over it, read back an empty_zero_page pointer to defeat KASLR, then overwrite a PTE to reach core_pattern.

Discovery

The vulnerability was found and reported by Billy Jheng Bing-Jhong and Muhammad Alifa Ramdhan of STAR Labs SG Pte. Ltd., who reported it to the Linux kernel security team on 2025-08-12. The fix landed in the stable trees and the CVE was published on 2025-09-05. STAR Labs published an advisory describing the record sequence and the privilege-escalation impact, and a public n-day write-up later detailed a full exploitation chain.

Exploitation Context

CISA added CVE-2025-39682 to the Known Exploited Vulnerabilities catalog on 2026-09-18 on evidence of active exploitation, a year after the patch shipped. CISA has not named a threat actor, described the intrusions, or published indicators, and no vendor reporting tying the bug to a specific campaign had appeared at the time of writing. The gap between the September 2025 fix and the 2026 KEV listing fits the usual pattern for kernel LPE bugs: the public exploitation chain becomes a post-compromise privilege-escalation step used against hosts that were never rebooted onto a patched kernel.

Exposure is not measurable with internet scanning the way an appliance CVE is, because kTLS is a socket option rather than a listening service. The practical population is long-lived Linux servers running unpatched 6.1, 6.6 or 6.12 stable kernels, and container hosts where the kernel is shared by every tenant. Note that a container escape is not needed: any local code execution, including code running inside an unprivileged container, reaches the same syscalls.

Remediation

  1. Patch to a fixed kernel: 6.1.149, 6.6.103, 6.12.44, 6.16.4, or 6.17-rc3 and later. On Ubuntu install linux 6.8.0-86.87 or later for 24.04 LTS and 6.14.0-34.34 or later for 25.04, and take the matching cloud-variant package where you run linux-aws, linux-azure, or linux-gcp. On Red Hat and other distributions apply the vendor errata tracked against this CVE.
  2. Reboot after installing. A patched package on disk does nothing while the vulnerable kernel is still running. Use livepatch where your distribution ships one for this CVE and a reboot must wait.
  3. Where patching is delayed, inventory what actually enables kTLS receive. Disabling kTLS in the application, for example building or configuring nginx without ssl_conf_command Options KTLS style offload, removes the affected code path at a throughput cost. Unloading the tls module is only viable if nothing on the host requests it.
  4. Reduce local execution surface on unpatched hosts: restrict untrusted local users and unprivileged containers, and keep seccomp profiles that deny unnecessary access to splice and pipe primitives where your workloads tolerate it.
  5. Review logs and crash data for kernel oopses or panics in tls_sw_recvmsg, tls_rx_rec_done, or tls_sw_release_resources_rx, and for unexplained core_pattern changes. Failed exploitation attempts typically leave a kernel crash behind.
  6. Federal civilian executive branch agencies must remediate by 2026-09-21 under CISA BOD 26-04. Treat that date as the target for any internet-facing or multi-tenant Linux host regardless of sector.

Key Details

PropertyValue
CVE ID CVE-2025-39682
Vendor / Product Linux — Kernel
NVD Published2025-09-05
NVD Last Modified2026-09-18
CVSS 3.1 Score9.8
CVSS 3.1 VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
SeverityCRITICAL
CISA KEV Added2026-09-18
CISA KEV Deadline2026-09-21
Known Ransomware Use No

CVSS 3.1 Breakdown

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Required Action

CISA BOD 22-01 Deadline: 2026-09-21. Apply mitigations in accordance with vendor instructions, ensuring compliance with CISA’s BOD 26-04 Prioritizing Security Updates Based on Risk (see URL in Notes) guidance and CISA’s “Forensics Triage Requirements” (see URL in Notes). Follow applicable BOD 26-04 guidance for cloud services or discontinue use of the product if mitigations are unavailable. Stakeholders are responsible for evaluating each asset's internet exposure and ensuring adherence to BOD 26-04 patching guidelines.

Timeline

DateEvent
2025-08-12Reported to the Linux kernel security team by STAR Labs SG
2025-09-05Fix merged to stable trees and CVE published
2026-09-18Added to CISA Known Exploited Vulnerabilities catalog on evidence of active exploitation
2026-09-21CISA BOD 26-04 remediation deadline