FlawOpen

flawopen.com/Teardowns/cve-2025-39682-linux-ktls-zero-length-record-mishandling

● CVE-2025-39682 · CVSS 9.8 · 緊急
セキュリティ研究 · FlawOpen

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
💡 わかりやすい解説 (ELI5)

各トレイには同じ分類の手紙だけを入れる郵便仕分けを想像してください。空の封筒にも分類はありますが、古い仕分け機は手紙の枚数でトレイを変えるか決めていました。枚数がゼロだと封筒の分類を無視し、次の種類まで同じトレイに混ぜてしまいます。カーネルの修正は封筒にデータがなくても分類マーカーを確認します。

主要な概念と専門用語

kTLS
カーネル TLS。Linux は接続済み TCP ソケットの TLS レコードをカーネル内で処理できる。
recvmsg()
アプリケーションと kTLS 受信経路が使うソケット受信システムコール。
TLS コンテンツ型
アプリケーションデータや制御レコードなど、レコードを分類するフィールド。
rx_list
後続の recvmsg 呼び出しで処理される受信待ちレコードのキュー。
CWE-754
異常または例外的な条件のチェック不備。NVD は CWE-754 を掲載し、CISA-ADP に帰属させています。Linux の CVE レコード自体には CWE の割り当てがありません。

フレームワーク対応

根本原因の分析 (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 使用状況とベンダーのカーネル状態に基づいて影響を評価してください。

ステップ・バイ・ステップの攻撃フロー

ステップ 1

kTLS がレコードを受信

アプリケーションはカーネル TLS 受信が有効な TCP ソケットを使う。

ステップ 2

キュー先頭の空の非DATAレコードを処理

rx_list の最初のレコードにペイロードがない場合に発生する。型を報告してもコピー済みバイト数はゼロになり得る。

ステップ 3

古い条件はコピー済みバイト数に依存

copied がゼロだと、処理済みレコードが非DATAかどうかを確認しない。

ステップ 4

受信ループが型の境界を越える

後続データが同じ recvmsg 呼び出しで処理され、単一型の制約に反する可能性がある。 Linux の CVSS 評価では、カーネルヒープ情報のユーザー空間への漏えい、メモリ破損、リモートからのカーネルクラッシュが起こり得る影響として記載されています。これは評価上の影響であり、すべての対象システムで各結果が発生するという意味ではありません。

ステップ 5

修正は意味上のマーカーを確認

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;

エンジニアリング&システム堅牢化チェックリスト

参考資料