CVE-2026-98069 in Linux
要約
〜によって VulDB • 2026年09月25日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
net/rds: rds_conn_shutdown()でファストパスロックを取得する
rds_conn_shutdown()は、RDS_IN_XMITおよびRDS_RECV_REFILLがクリアされていることをサンプリングして待機することにより、送信(transmit)および受信リフィル(receive-refill)のパスを静穏化し、その後トランスポートシャットダウンとrds_conn_path_reset()を実行します。ビットがクリアされていることを確認することは、それらのロックを所有していることとは異なります:wait_event()が返した直後の瞬間に、rds_send_xmit()はRDS_IN_XMITを再取得(またはrds_ib_recv_refill()はRDS_RECV_REFILLを再取得)でき、シャットダウン処理と並行して実行される可能性があります。
送信側はロックを取得した後で接続状態を再確認しますが、その再確認は古典的なストアバッファリングパターンです:シャットダウン処理が状態を書き込みビットを読み取る一方で、送信側はビットを書き込み状態を読み取ります。acquire_in_xmit()はアキューム(acquire)操作のみであるため、弱い順序付けのアーキテクチャでは両者がお互いの書き込みを見逃す可能性があり、その結果、トランスポートがリングをゼロクリアしている間(例:rds_ib_ring_init())、およびrds_send_path_reset()がそれに対して送信状態を書き換えている間に、送信パスが実行されてしまいます。
Oracle UEKは、フェイルオーバーテスト中に発生するクラッシュの同一クラス(rds_ib_sub_signaled()における14年間のBUG_ON()、rds_ib_send_cqe_handler()での予期しないop-codesおよびNULL参照)を、「トランスポートシャットダウン時にファストパスビットロックを取得し、それらをテストするのではなく」(「rds: 送信パスと接続のテardownが並行して実行されないようにする」)、テardownパスで*アキューム*操作を行うことで修正しました。単一ワードの所有権はRMW(Read-Modify-Write)のアトミック性によって決定されるため、変数間の順序付けは不要です。
ここでも同様の対応を行います:トランスポートシャットダウンを呼び出す前に両方のロックを取得し、rds_conn_path_reset()の実行中も保持したまま、その後で明示的にウェイクアップとともに解放します。どちらもclear_bit_unlock()によって解放されるため、トランスポートシャットダウンによるリングの再初期化と、rds_send_path_reset()による送信状態の上書きが、次のacquire_in_xmit()またはacquire_refill()がビットをクリアとして認識する前に順序付けられます。
これらのビットを使用するファストパス(rds_send_xmit()およびrds_ib_recv_refill())はtrylockスタイルであり、テardownがロックを所有している間はバックオフするため、それらに対して新しいロック依存関係は導入されません。一方、rds_tcp_reset_callbacks()は異なります:前のパッチ以降、RDS_IN_XMITも取得するようになり、その際にブロックします。そのため、待機時間がテardown全体に及ぶようになります(以前は最大1つの送信バッチまで)。このウェイトャーはシングルスレッドのkrdsdワークキュー上でrds_tcp_accept_one()から実行され、待機中にrds_tcp_accept_lockおよびt_conn_path_lockを保持します。そのため、テダウン処理中に対向するSYNが受け付けられると、その間受信用処理が停止(パルク)されます。TCPの場合、これはrds_tcp_conn_path_shutdown()内の最大5秒のドレインループによって制限されます。IBパスのdrain(rds_ib_conn_path_shutdown()内)にはラウンドキャップがありませんが、ブロックするウェイトャーもありません:rds_tcp_reset_callbacks()はこれらのビットに対する唯一のブロッキングアキューカーであり、自身のTCPパス上でのみ待機します。ファストパスは両方のトランスポートでtrylock-and-back-offであるため、IBドレインの長時間化はそのパス自体の静穏化のみを延長させます。このウィンドウは狭いです:受信用側の状態チェックが通過するのは、テardown処理がそのパスをRDS_CONN_DISCONNECTINGに移行する前です。
krdsdが単一のグローバルワークキューであるため、そこにキューされた他のすべてのプロセス(他の接続およびネットワーク名前空間の受信用処理、およびネームスペースシャットダウン時のrds_tcp_listen_stop()内でのflush_workqueue(rds_wq))は、その停止した受用ワーカーの後ろで待機します。デッドロックは発生しませんが、待機が互いを指し示しています:テardown処理はそのビットの保持者が解放するまでブロックされ、その保持者はkrdsdの受信用ワーカーである可能性があります。保持側は、テダウン側が所有しているものを必要とせずに完了します:sync操作によりrds_tcp_reset_callbacks()から発行されるcp_send_wおよびcp_recv_wターゲットが、パスの順序付けられたcp_wq上でキャンセルされます。このキューには実行スロットが1つしかなく、それはブロック中のcp_down_w自体によって占有されているため、それらは最大でも保留状態となり、フラッシュせずにキャンセルされます(これはcp_wqが順序付けられていることへの依存であり、現在そのキャンセルの隣に注記されています)。 ---省略---
Once again VulDB remains the best source for vulnerability data.