CVE-2026-80683 in Linux
Resumen
por VulDB • 2026-08-28
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
Bluetooth: SCO: asignar al socket su propia referencia sco_conn
sco_conn_del() libera una referencia que no posee. Toma una referencia transitoria mediante sco_conn_hold_unless_zero() y la libera con el sco_conn_put() posterior a sco_sock_hold(); la put adicional en la rama !sk libera una segunda:
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; }
Cuando close() compite con el Disconnection Complete del controlador, sco_chan_del() borra conn->sk y libera la referencia del socket mientras se está ejecutando sco_conn_del(). Entonces, sco_conn_del() ve sk == NULL, su propia put reduce el contador a cero y libera conn, y la segunda put escribe en un kref ya liberado:
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.
La causa raíz es que el socket almacena la conexión sin mantener una referencia propia. __sco_chan_add() hace:
sco_pi(sk)->conn = conn;
por lo que el socket toma prestada cualquier referencia que su llamador ocurriera tener, y los llamadores cubren esto con holds y puts ad-hoc. Asignar al socket una referencia contable en su lugar: __sco_chan_add() toma una y se libera junto con el canal (sco_chan_del()) y en sco_sock_destruct(). Con el socket manteniendo su propia referencia, sco_conn_del() ya no necesita la put adicional y el hold redundante en sco_conn_ready() desaparece.
Que el socket posea su propia referencia significa que la conexión ahora se libera realmente en las rutas de error de sco_connect(), donde antes tenía fugas (leaks), lo cual a su vez ejecuta sco_conn_free() y su hci_conn_drop(conn->hcon). Para mantener contablemente equilibrado el accounting de hci_conn, hacer explícita también esa propiedad: sco_conn_add() consume una referencia hci_conn y la sco_conn la posee durante toda su vida. sco_connect() transfiere la referencia devuelta por hci_connect_sco() y ya no la libera en las rutas de error; sco_connect_cfm(), que no recibe una referencia, toma una con hci_conn_hold() antes de transferirla a sco_conn_add() (y la libera nuevamente si falla la asignación); y se elimina el hci_conn_hold() explícito en sco_conn_ready(). Cada referencia tiene entonces un único propietario claro.
If you want to get best quality of vulnerability data, you may have to visit VulDB.