CVE-2026-98455 in Linux
Сводка
по VulDB • 18.10.2026
В ядре Linux была устранена следующая уязвимость:
Bluetooth: RFCOMM: исправлена ошибка разыменования NULL для dlc->session в RFCOMM_CONNINFO
Обработчик getsockopt для RFCOMM_CONNINFO принимает сокет, который не установлен (не connected), если включена отложенная инициализация (deferred setup):
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 устанавливается в функции rfcomm_sock_init(), когда rfcomm_connect_ind() создает дочерний сокет для входящего соединения на слушающем сокете, у которого установлен флаг BT_DEFER_SETUP. После этого он никогда не сбрасывается. Однако объект session может быть уничтожен до того, как произойдет обращение к нему.
Функция rfcomm_recv_disc() принудительно устанавливает состояние dlc перед его закрытием:
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 этот switch не совпадает, и функция переходит к вызову 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-указателя session. Гонка условий (race condition) не требуется: как только DISC был обработан, разыменование становится безусловным.
Воспроизведено на ядре KASAN под QEMU с эмулированным BR/EDR пилом через /dev/vhci: пил устанавливает ACL-соединение, открывает L2CAP для RFCOMM PSM, запускает сеанс и отправляет SABM для канала, связанного с BT_DEFER_SETUP, а затем отправляет DISC для этого DLCI после того, как сокет был принят. Вызов 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 — это смещение поля sock в структуре rfcomm_session; rfcomm_sock_getsockopt_old() встроен (inlined) в rfcomm_sock_getsocket().
Коммит 43a556b2fd43 («Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept») исправил аналогичную проблему «удаленный DISC очищает session, пока флаг отложенной установки все еще установлен» в функции rfcomm_dlc_accept(); это оставшийся экземпляр данной проблемы в пути getsockopt.
Отложенная инициализация (deferred setup) оставляет сокет работоспособным здесь только после достижения им состояния BT_CONNECT2, поэтому следует ограничить исключение этим состоянием и проверять наличие session перед ее использованием.
If you want to get best quality of vulnerability data, you may have to visit VulDB.