flawopen.com/Teardowns/cve-2024-26585-linux-tls-tx-work-close-race
CVE-2024-26585:Linux TLS の終了競合
Linux kTLS では TX work の登録前に sendmsg/recvmsg が起床する可能性がありました。修正は work を先に登録します。
作業者が最後の仕事を共有キューに入れる前に、待っている同僚へ「完了」と伝える場面を想像してください。その隙に同僚が店を閉めて既存の仕事を取り消し、作業者が後から仕事を追加する可能性があります。カーネルの修正は TLS 送信 work を登録してから完了を通知します。
主要な概念と専門用語
kTLS- TLS レコード処理を Linux カーネルのネットワーク経路で行う機能です。
非同期暗号の完了- 非同期 TLS 暗号処理の終了後に実行される callback です。
`complete()`- 操作の完了を待つスレッドを起こす Linux completion primitive です。
遅延 TX work- 暗号処理後に TLS レコード送信を続ける、キュー登録済みのカーネル work です。
フレームワーク対応
- このガイドで説明する弱点の CWE 参照: CWE-362
根本原因の分析 (Root Cause)
net/tls/tls_sw.c の tls_encrypt_done() は、先頭レコードの遅延 TX work を登録する前に sendmsg()/recvmsg() の待機スレッドへ complete() を呼ぶ可能性がありました。起床したスレッドが戻って socket を閉じる一方、callback はまだ work を登録しようとしているため、socket close と TX work 登録が競合します。upstream commit e01e3934a1b2 は順序を反転し、レコードが ctx->tx_list の先頭なら complete() より前に ctx->tx_work を登録します。CVE 通知が示すのは競合です。引用元は、以前の MSG_ZEROCOPY、解放済みネットワークページ、メモリ上書き、refcount_inc_not_zero() による修正の主張を裏付けていません。
ステップ・バイ・ステップの攻撃フロー
1. TLS 送信開始
プロセスが kTLS の送信経路を使用し、レコード暗号化が非同期で完了する場合があります。
2. callback が順序を確認
tls_encrypt_done() は完了したレコードが ctx->tx_list の先頭かを確認します。
3. 起床と close が競合
修正前は complete() でスレッドを起こした後に TX work を登録する場合があり、その間にスレッドが socket を閉じる可能性がありました。
4. 修正で順序を固定
遅延 TX work を先に登録し、その後で完了を通知するため、登録前にスレッドが先へ進めません。
ソースコード比較:脆弱 vs 堅牢化
// e01e3934a1b2 適用前の net/tls/tls_sw.c における関連する順序
bool ready = false;
if (rec == first_rec)
ready = true;
if (atomic_dec_and_test(&ctx->encrypt_pending))
complete(&ctx->async_wait.completion);
if (!ready)
return;
if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
schedule_delayed_work(&ctx->tx_work.work, 1);
// e01e3934a1b2 適用後の net/tls/tls_sw.c における関連する順序
if (rec == first_rec) {
// 送信を依頼したスレッドを起こす前に、送信処理をキューへ追加する。
if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask))
schedule_delayed_work(&ctx->tx_work.work, 1);
}
if (atomic_dec_and_test(&ctx->encrypt_pending))
complete(&ctx->async_wait.completion);
エンジニアリング&システム堅牢化チェックリスト
- ✓
CVE-2024-26585の修正を backport したサポート対象ディストリビューションカーネルへ更新します。安定版は backport するため、ベンダー告知を確認してください。 - ✓非同期 callback では、起床したスレッドが共有オブジェクトを閉じ得る場合、完了通知より先に後続 work をキューへ登録します。
- ✓close 時に callback work を同期的に cancel または flush し、キャンセル後に callback が新しい work を登録できないようにします。
- ✓非同期 TLS 完了と socket close を競合させ、work の登録順を検証する制御された並行性テストを追加します。
- ✓
MSG_ZEROCOPYやハードウェア暗号をこの CVE の前提としないでください。upstream の説明は非同期暗号完了と TX work のスケジューリングです。