flawopen.com/Teardowns/cve-2025-39682-linux-ktls-zero-length-record-mishandling
Linux CVE-2025-39682:kTLS のゼロ長レコード処理不備
Linux の kTLS 受信キューにある長さゼロの非DATA TLSレコードが、recvmsg ごとのレコード型チェックを迂回する可能性がありました。修正ではコピーされたバイト数がゼロでも処理済みの型を確認します。 Linux の CVSS 評価では、カーネルヒープ情報のユーザー空間への漏えい、メモリ破損、リモートからのカーネルクラッシュが起こり得る影響として記載されています。これは評価上の影響であり、すべての対象システムで各結果が発生するという意味ではありません。
CVSS ベクトル
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H各トレイには同じ分類の手紙だけを入れる郵便仕分けを想像してください。空の封筒にも分類はありますが、古い仕分け機は手紙の枚数でトレイを変えるか決めていました。枚数がゼロだと封筒の分類を無視し、次の種類まで同じトレイに混ぜてしまいます。カーネルの修正は封筒にデータがなくても分類マーカーを確認します。
主要な概念と専門用語
kTLS- カーネル TLS。Linux は接続済み TCP ソケットの TLS レコードをカーネル内で処理できる。
recvmsg()- アプリケーションと kTLS 受信経路が使うソケット受信システムコール。
TLS コンテンツ型- アプリケーションデータや制御レコードなど、レコードを分類するフィールド。
rx_list- 後続の recvmsg 呼び出しで処理される受信待ちレコードのキュー。
CWE-754- 異常または例外的な条件のチェック不備。NVD は
CWE-754を掲載し、CISA-ADP に帰属させています。Linux の CVE レコード自体には CWE の割り当てがありません。
フレームワーク対応
- このガイドで説明する弱点の CWE 参照: CWE-754
- CISA KEV — 追加日 2026-09-18 — CVE-2025-39682
根本原因の分析 (Root Cause)
Linux の kTLS 受信処理は、1回の recvmsg() で連続する DATA レコードか、単一の非DATAレコードを返す必要があります。process_rx_list() が最初の長さゼロの非DATAレコードを処理すると、TLS の型を設定しながら err == 0 を返す場合があります。tls_sw_recvmsg() はそのゼロを copied に設定し、停止条件に (copied && control != TLS_RECORD_TYPE_DATA) を使っていました。copied がゼロのため、処理済みレコードの型が無視され、後続データの処理が続いていました。上流修正は control を直接確認します。型が設定済みでDATAでなければ停止し、ゼロは「型がまだ報告されていない」ことを示します。影響するのは Linux カーネル TLS 受信経路(kTLS)を有効にして利用する場合に限られ、すべてのユーザー空間 TLS ライブラリのパーサーの問題ではありません。Linux が公開した CVSS 3.1 は 9.8 Critical(AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)です。実際の kTLS 使用状況とベンダーのカーネル状態に基づいて影響を評価してください。
ステップ・バイ・ステップの攻撃フロー
kTLS がレコードを受信
アプリケーションはカーネル TLS 受信が有効な TCP ソケットを使う。
キュー先頭の空の非DATAレコードを処理
rx_list の最初のレコードにペイロードがない場合に発生する。型を報告してもコピー済みバイト数はゼロになり得る。
古い条件はコピー済みバイト数に依存
copied がゼロだと、処理済みレコードが非DATAかどうかを確認しない。
受信ループが型の境界を越える
後続データが同じ recvmsg 呼び出しで処理され、単一型の制約に反する可能性がある。 Linux の CVSS 評価では、カーネルヒープ情報のユーザー空間への漏えい、メモリ破損、リモートからのカーネルクラッシュが起こり得る影響として記載されています。これは評価上の影響であり、すべての対象システムで各結果が発生するという意味ではありません。
修正は意味上のマーカーを確認
control が設定済みの非DATA型を示す場合、コピー量にかかわらず停止する。
ソースコード比較:脆弱 vs 堅牢化
net/tls/tls_sw.c の抜粋であり、関数全体ではありません。上流修正はコピーしたバイト数ではなく、報告済みコンテンツ型マーカーを停止条件に使います。control == 0 は型未報告を意味し、設定済みの非DATA型ならこの recvmsg 呼び出しを停止します。上流パッチの正確なロジック変更です。
ソース抜粋: ソースコード:net/tls/tls_sw.c
copied = err;
if (len <= copied ||
(copied && control != TLS_RECORD_TYPE_DATA) || rx_more)
goto end;
copied = err;
if (len <= copied || rx_more ||
(control && control != TLS_RECORD_TYPE_DATA))
goto end;
エンジニアリング&システム堅牢化チェックリスト
- ✓Linux kTLS 受信を有効にしているワークロードを調査する。通常のユーザー空間 TLS が自動的に影響を受けるわけではない。
- ✓修正を含むベンダーのカーネルパッケージへ更新し、正確なビルドと告知を確認する。
- ✓1回の recvmsg は連続 DATA レコードまたは単一の非DATAレコードだけを処理し、型境界を越えないという制約を維持する。
- ✓upstream の kTLS ゼロ長レコード回帰テストを実行または維持してください。下流の受信処理実装でも、空の非DATAレコードによって同じ呼び出しで次のレコードを消費しないことを検証します。
- ✓「型が未報告」と「コピーしたバイトがゼロ」を区別し、
controlのような意味状態を確認する。 - ✓更新が遅れる場合は kTLS に関するベンダーの緩和策に従い、必要なワークロードへの影響を確認する。