CVE-2026-98455 in Linux
要約
〜によって VulDB • 2026年10月18日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
Bluetooth: RFCOMM: RFCOMM_CONNINFO における dlc->session の NULL デリファレンスを修正する
RFCOMM_CONNINFO を取得するための getsockopt ハンドラは、遅延セットアップが有効な場合、接続されていないソケットも受け入れます。
```c if (sk->sk_state != BT_CONNECTED && !rfcomm_pi(sk)->dlc->defer_setup) {
err = -ENOTCONN; break; } l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; ```
`dlc->defer_setup` は、リスニングソケット上で `BT_DEFER_SETUP` が有効な場合の着信接続に対して子ソケットを作成する際に、`rfcomm_connect_ind()` 内で設定されます。その後、このフラグがクリアされることはありません。しかし、セッションはそれより前に消滅する可能性があります。
`rfcomm_recv_disc()` は、破棄する前に dlc の状態を強制的に以下のように変更します:
```c d->state = BT_CLOSED; __rfcomm_dlc_close(d, err); ```
`__rfcomm_dlc_close()` 内の RFCOMM_DEFER_SETUP による早期リターンは、BT_CONNECT、BT_CONFIG、BT_OPEN、および BT_CONNECT2 のみをカバーするため、状態がすでに BT_CLOSED である場合、そのスイッチ文は一致せず、関数は `rfcomm_dlc_unlink()` にフォールスルーします。これにより `d->session = NULL` が設定されますが、`d->defer_setup` は 1 のまま残ります。
その後、受け入れられたソケットに対して `getsockopt(SOL_RFCOMM, RFCOMM_CONNINFO)` を実行すると、-ENOTCONN パス(`sk->sk_state` は BT_CLOSED ですが、`dlc->defer_setup` はまだ設定されているため)がスキップされ、NULL のセッションへのデリファレンスが実行されます。競合条件は必要ありません:DISC が処理されると、そのデリファレンスは無条件に行われます。
QEMU 上の KASAN カーネルで再現されました(/dev/vhci を介してエミュレートされた BR/EDR ピアを使用)。ピアは ACL リンクを確立し、RFCOMM PSM で L2CAP をオープンし、セッションを開始して `BT_DEFER_SETUP` とバインドされたチャネルに対して SABM を送信します。その後、ソケットが受け入れられた後にその dlci に対して DISC を送信します。すると、受け入れられたソケットに対する `getsockopt(SOL_RFCOMM, RFCOMM_CONNINFO)` で以下が発生します:
``` Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] SMP KASAN PTI
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
CPU: 1 UID: 0 PID: 150 Comm: init Tainted: G B 7.3.0-rc3-g5dd1818b15d9 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) RIP: 0010:rfcomm_sock_getsockopt+0x529/0x780 Call Trace: <TASK> do_sock_getsockopt+0x3ad/0x7d0 __sys_getsockopt+0x10e/0x1b0 __x64_sys_getsockopt+0xc2/0x160 do_syscall_64+0xda/0x4b0 entry_SYSCALL_64_after_hwframe+0x77/0x7f </TASK> ```
0x10 は `struct rfcomm_session` における sock のオフセットです。 `rfcomm_sock_getsockopt_old()` は `rfcomm_sock_getsockopt()` にインライン展開されています。
コミット 43a556b2fd43(「Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept」)は、同じ「リモート DISC がセッションをクリアするが、遅延セットアップフラグはまだ設定されている」という問題を `rfcomm_dlc_accept()` で修正しました。これはその残りのインスタンスであり、getsockopt パスにおけるものです。
遅延セットアップは、ソケットが BT_CONNECT2 に到達した後にのみここで使用可能になるため、例外をその状態に制限し、セッションが実際に存在することを確認してからそれを追跡するようにします。
If you want to get best quality of vulnerability data, you may have to visit VulDB.