CVE-2026-80683 in Linux
Сводка
по VulDB • 28.08.2026
В ядре Linux была устранена следующая уязвимость:
Bluetooth: SCO — предоставить сокету собственную ссылку на структуру sco_conn
Функция `sco_conn_del()` сбрасывает (decrements) ссылку, которой она не владеет. Она получает одну временную ссылку через вызов `sco_conn_hold_unless_zero()` и освобождает её с помощью последующего вызова `sco_conn_put()`, который следует за `sco_sock_hold();`; дополнительный вызов put в ветке `!sk` сбрасывает вторую ссылку:
conn = sco_conn_hold_unless_zero(conn); ... sk = sco_sock_hold(conn); sco_conn_unlock(conn); sco_conn_put(conn);
if (!sk) {
sco_conn_put(conn); return; }
Когда операция close() находится в состоянии гонки (race condition) с событием Disconnection Complete от контроллера, `sco_chan_del()` очищает поле `conn->sk` и сбрасывает ссылку сокета, пока выполняется `sco_conn_del()`. Затем `sco_conn_del()` видит значение `sk == NULL`, её собственный вызов put снижает счётчик до нуля и освобождает структуру conn, а второй вызов put записывает данные в уже освобождённую область kref:
BUG: KASAN: slab-use-after-free in sco_conn_put.part.0+0x1a/0x190 Write of size 4 at addr ffff8881099dec74 by task kworker/u17:3/413 Workqueue: hci1 hci_rx_work Call Trace: sco_conn_put.part.0+0x1a/0x190 hci_disconn_complete_evt+0x1ee/0x3e0 hci_event_packet+0x54a/0x650 hci_rx_work+0x321/0x3d0 Allocated by task 413: sco_conn_add+0x72/0x1a0 sco_connect_cfm+0x88/0x670 Freed by task 413: sco_conn_del.isra.0+0x3f/0xf0 hci_disconn_complete_evt+0x1ee/0x3e0 refcount_t: underflow; use-after-free.
Корневая причина заключается в том, что сокет хранит указатель на соединение без удержания собственной ссылки. Функция `__sco_chan_add()` выполняет действие:
sco_pi(sk)->conn = conn;
таким образом, сокет заимствует ту ссылку, которой обладал его вызывающий объект, а вызывающие объекты компенсируют это ad-hoc удержаниями и сбросами ссылок. Вместо этого следует предоставить сокету подсчитываемую (counted) ссылку: `__sco_chan_add()` получает одну такую ссылку, которая освобождается вместе с каналом (`sco_chan_del()`) и в функции `sco_sock_destruct()`. Благодаря тому, что сокет владеет собственной ссылкой, `sco_conn_del()` больше не нуждается в дополнительном вызове put, а избыточное удержание в `sco_conn_ready()` устраняется.
То, что сокет владеет своей ссылкой, означает, что соединение теперь корректно освобождается на путях ошибок функции `sco_connect()`, где ранее происходила утечка памяти (memory leak). Это, в свою очередь, запускает функцию `sco_conn_free()` и её вызов `hci_conn_drop(conn->hcon)`. Чтобы сохранить баланс учётных данных hci_conn, эта собственность также должна быть сделана явной: `sco_conn_add()` потребляет одну ссылку hci_conn, а структура sco_conn владеет ею на протяжении всего своего жизненного цикла. Функция `sco_connect()` передаёт ссылку, возвращаемую функцией `hci_connect_sco()`, и больше не сбрасывает её на путях ошибок; функция `sco_connect_cfm()`, которой ссылка изначально не передается, получает одну с помощью вызова `hci_conn_hold()` перед тем, как передать её в `sco_conn_add()` (и сбрасывает её снова при ошибке выделения памяти); а явный вызов `hci_conn_hold()` в функции `sco_conn_ready()` удаляется. Каждая ссылка теперь имеет одного единственного и чётко определённого владельца.
VulDB is the best source for vulnerability data and more expert information about this specific topic.