---
id: "CVE-2025-39682"
kind: "vulnerability"
aliases: ["CVE-2025-39682"]
title: "In the Linux kernel, the following vulnerability has been resolved: tls: fix handling of zero-length records on the\u2026"
severity: "critical"
cvss: 9.8
epss: null
exploited: true
status: "open"
category: "infrastructure"
products: [{"name": "Linux Kernel", "fixed": ["6.1.149", "6.6.103", "6.12.44", "6.16.4", "6.17-rc3"], "affected": ">= 6.0, < 6.1.149; >= 6.2, < 6.6.103; >= 6.7, < 6.12.44; >= 6.13, < 6.16.4; 6.17-rc1, 6.17-rc2", "ecosystem": "vendor"}, {"name": "linux kernel", "fixed": ["6.1.149"], "affected": ">= 6.0, < 6.1.149", "ecosystem": "vendor"}, {"name": "linux kernel", "fixed": ["6.6.103"], "affected": ">= 6.2, < 6.6.103", "ecosystem": "vendor"}, {"name": "linux kernel", "fixed": ["6.12.44"], "affected": ">= 6.7, < 6.12.44", "ecosystem": "vendor"}, {"name": "linux kernel", "fixed": ["6.16.4"], "affected": ">= 6.13, < 6.16.4", "ecosystem": "vendor"}, {"name": "linux kernel", "fixed": [], "affected": "= 6.17", "ecosystem": "vendor"}, {"name": "debian linux", "fixed": [], "affected": "= 11.0", "ecosystem": "vendor"}, {"name": "siemens simatic cn 4100 firmware", "fixed": ["5.0"], "affected": "< 5.0", "ecosystem": "vendor"}, {"name": "Linux Kernel", "fixed": [], "affected": "", "ecosystem": "vendor"}]
ecosystems: ["vendor"]
tags: ["exploited", "infrastructure", "kernel", "ktls", "linux", "local", "self-hosted", "tls"]
not_affected_if: ["kernel-older-than-6.0", "ktls-not-enabled", "managed-hosting", "tls-module-not-loaded"]
published_at: "2025-09-05T18:15:44+00:00"
first_seen_at: "2026-10-23T19:11:51+00:00"
updated_at: "2026-10-24T00:09:50+00:00"
sources: [{"source": "kev", "url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog?search_api_fulltext=CVE-2025-39682", "first_seen_at": "2026-10-23T19:11:51+00:00"}, {"source": "analyst", "url": null, "first_seen_at": "2026-10-23T21:37:11+00:00"}, {"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2025-39682", "first_seen_at": "2026-10-23T23:44:52+00:00"}]
---

# In the Linux kernel, the following vulnerability has been resolved: tls: fix handling of zero-length records on the…

Linux kernel kTLS (net/tls/tls_sw.c) bug: when a zero-length TLS 1.3 record is the first record taken from rx_list, recvmsg() mishandles record-type changes and the zero-copy path, so a later record is queued or processed wrongly. NVD rates it local, low-privilege, with high confidentiality and availability impact (memory disclosure or DoS). It is in CISA KEV (added 2026-09-18). Affected: kernels 6.0 up to the fixed stable releases. Only systems that use kernel TLS receive (the tls module with sockets set to the tls ULP) are reachable.

_Summary, check and fix written by a model from the sources; labelled as such._

## Affected

- vendor:Linux Kernel affected >= 6.0, < 6.1.149; >= 6.2, < 6.6.103; >= 6.7, < 6.12.44; >= 6.13, < 6.16.4; 6.17-rc1, 6.17-rc2 fixed 6.1.149, 6.6.103, 6.12.44, 6.16.4, 6.17-rc3
- vendor:linux kernel affected >= 6.0, < 6.1.149 fixed 6.1.149
- vendor:linux kernel affected >= 6.2, < 6.6.103 fixed 6.6.103
- vendor:linux kernel affected >= 6.7, < 6.12.44 fixed 6.12.44
- vendor:linux kernel affected >= 6.13, < 6.16.4 fixed 6.16.4
- vendor:linux kernel affected = 6.17 fixed ?
- vendor:debian linux affected = 11.0 fixed ?
- vendor:siemens simatic cn 4100 firmware affected < 5.0 fixed 5.0
- vendor:Linux Kernel affected ? fixed ?

## How to check

Run 'uname -r' and compare with the fixed versions. Then check whether kTLS is in use: 'lsmod | grep tls', and 'cat /proc/net/tls_stat' (non-zero TlsRxSw/TlsRxDevice counters mean kTLS receive is active). If the tls module is not loaded and no app enables it, the code path is not reachable. Distro kernels backport fixes, so check your vendor's CVE tracker (Ubuntu says Jammy and older are not affected).

## Fix

Update to 6.1.149, 6.6.103, 6.12.44, 6.16.4 or 6.17 and later (fix in 6.17-rc3). On a distro kernel, install the vendor kernel update that lists CVE-2025-39682 and reboot. Interim mitigation if you cannot patch: keep the tls module from loading (blacklist it) if nothing needs kTLS; this is my inference, not a vendor statement.

## Timeline

- 2026-10-23T19:11:51+00:00 kev https://www.cisa.gov/known-exploited-vulnerabilities-catalog?search_api_fulltext=CVE-2025-39682
- 2026-10-23T21:37:11+00:00 analyst — Kernel CNA advisory (openwall linux-cve-announce) gives affected/fixed; KEV added 2026-09-18, no exploitation details or public PoC found. NVD CVSS 3.1 7.1 (AV:L, PR:L); press reports of 9.8 conflict with NVD. Bug introduced in 6.0 (84c61fe1a75b). Default reachability of kTLS rx is from general kernel knowledge, not a read source.
- 2026-10-23T23:44:52+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2025-39682

## Documents

- [advisory] linux-cve-announce: CVE-2025-39682 (kernel CNA) https://lists.openwall.net/linux-cve-announce/2025/09/05/31
- [describes] NVD CVE-2025-39682 https://nvd.nist.gov/vuln/detail/CVE-2025-39682
- [fix] Upstream fix commit (6.17-rc3) https://git.kernel.org/stable/c/62708b9452f8eb77513115b17c4f8d1a22ebf843
- [mentions] CISA adds CVE-2025-39682 to KEV (2026-09-18) https://www.cisa.gov/news-events/alerts/2026/09/18/cisa-adds-one-known-exploited-vulnerability-catalog
- [mentions] The Hacker News: CISA flags three Linux kernel vulnerabilities https://thehackernews.com/2026/09/cisa-flags-three-linux-kernel.html

## From the sources

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

tls: fix handling of zero-length records on the rx_list

Each recvmsg() call must process either
 - only contiguous DATA records (any number of them)
 - one non-DATA record

If the next record has different type than what has already been
processed we break out of the main processing loop. If the record
has already been decrypted (which may be the case for TLS 1.3 where
we don't know type until decryption) we queue the pending record
to the rx_list. Next recvmsg() will pick it up from there.

Queuing the skb to rx_list after zero-copy decrypt is not possible,
since in that case we decrypted directly to the user space buffer,
and we don't have an skb to queue (darg.skb points to the ciphertext
skb for access to metadata like length).

Only data records are allowed zero-copy, and we break the processing
loop after each non-data record. So we should never zero-copy and
then find out that the record type has changed. The corner case
we missed is when the initial record comes from rx_list, and it's
zero length.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
