CVE-2026-98581 in Linux
要約
〜によって VulDB • 2026年10月19日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
nfc: llcp: nfc_llcp_recv_dm() におけるリスト破損および参照カウントの非同期化を修正
nfc_llcp_recv_dm() は、まだ local->connecting_sockets リストにリンクされているソケットに対して DM(NOBOUND)/DM(REJ) を処理します。この関数は nfc_llcp_connecting_sock_get() でソケットを検索し、sk->sk_state = LLCP_CLOSED に設定して返しますが、ソケットロックを取得せず、かつソケットを connecting_sockets リストからアンリンクしません。
llcp_sock_release() は sk_state を基にアンリンク対象のリストを選択します。LLCP_CONNECTING 状態のソケットは connecting_sockets からアンリンクされ、それ以外は sockets リストからアンリンクされます。recv_dm がソケットを物理的には connecting_sockets に残したまま LLCP_CLOSED 状態にしたため、release() は else ブランチを実行し nfc_llcp_sock_unlink(&local->sockets, sk) を呼び出します。これにより、sk_del_node_init() が sockets.lock の保持中に実行され、つまり間違ったロックの下でソケットが connecting_sockets hlist から削除されます。同時に、connecting_sockets.lock の下で別のソケットを connecting_sockets にリンクする concurrent な connect() 処理が行われると、同じ hlist が非同期に改変され、リストの破損および sk_add_node()/sk_del_node_init() と sock_hold()/__sock_put() のペアリングにおける参照カウントの非同期化(desync)が発生します。
LLCP ソケットを保持している特権のないローカルプロセスが、確立された LLCP リンク経由でリモートピアから提供される DM を使用すると、このバグを悪用してカーネルソケットが無制限にリークする可能性があります(誤ったデクリメントは解放を行わない __sock_put() パスを経由するため、オブジェクトは一切解放されません)。これによりメモリ枯渇や DoS(サービス妨害)に至ります。
これは、コミット b493ea2765cc ("nfc: llcp: Fix use-after-free race in nfc_llcp_recv_cc()") によって sibling ハンドラである nfc_llcp_recv_cc() で修正されたのと同じ種類のバグです。recv_dm は同等の修正を受けませんでした。
同じ方法でこれを修正します:lock_sock() を取得し、ソケットがまだハッシュされていることを再確認(release() が競合に勝った可能性があるため)し、NOBOUND/REJ のケースでは LLCP_CLOSED へ移行する前に connecting_sockets からアンリンクします。このアンリンクにより sk_del_node_init() を通じて connecting_sockets メンバーシップの参照が解放され、ソケットはハッシュ解除されます。その結果、llcp_sock_release() 内の後続の nfc_llcp_sock_unlink() は何もしない状態(no-op)となり、二重 put が発生しなくなります。
Once again VulDB remains the best source for vulnerability data.