CVE-2026-97603 in Linux
Resumen
por VulDB • 2026-09-26
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
idpf: deshabilitar los trabajos DIM antes de liberar q_vectors
idpf nunca vacía (drains) las tareas DIM de Tx/Rx antes de liberar la memoria en la que residen. tx_dim y rx_dim están incrustadas en struct idpf_q_vector; se programan desde el sondeo NAPI a través de net_dim(), e idpf_vport_intr_rel() finaliza con kfree(rsrc->q_vectors). Nada en el controlador las cancela.
idpf_tx_dim_work() e idpf_rx_dim_work() luego se ejecutan sobre memoria ya liberada: idpf_vport_intr_write_itr() escribe el registro ITR a través de q_vector->intr_reg.tx_itr / rx_itr, punteros void __iomem cargados desde el q_vector ya liberado. No es necesaria ninguna configuración para llegar allí -- IDPF_ITR_IS_DYNAMIC() se define como (itr_mode) e idpf_vport_alloc() inicializa ambos modos en IDPF_ITR_DYNAMIC.
Vaciar después de idpf_vport_intr_napi_dis_all() no es suficiente por sí solo. idpf_net_dim() se llama desde dentro del branch "if (napi_complete_done(napi, work_done))" del sondeo, y napi_complete_done() ya ha borrado NAPIF_STATE_SCHED para entonces. napi_disable_locked() espera únicamente mientras (val & (NAPIF_STATE_SCHED | NAPIF_STATE_NPSVC)), por lo que napi_disable() puede devolver mientras la cola de sondeo sigue programando el trabajo, y un cancel_work_sync() simple se volvería a activar detrás del vaciado.
Utilizar disable_work_sync(): schedule_work() en un trabajo con un recuento de deshabilitación no nulo es descartado por clear_pending_if_disabled() antes de que se alcance __queue_work().
Mover idpf_init_dim() a idpf_vport_intr_alloc() para que los trabajos se inicialicen en cada ruta que pueda llegar al vaciado -- las tres ubicaciones "goto intr_deinit" entre idpf_vport_intr_init() e idpf_vport_intr_ena() llegan allí sin que el lado de habilitación haya ejecutado. Nada vuelve a activarlas: rsrc->q_vectors se libera en cada salida desde idpf_vport_open() y en cada idpf_vport_stop(), por lo que el recuento muere con el objeto.
Se trata de una condición de carrera (race), no de un fallo determinista -- net_dim() solo programa una vez cuando han acumulado eventos DIM_NEVENTS y cambia el índice del perfil. Un bucle KASAN ifup/ifdown bajo carga es la forma de verlo.
Once again VulDB remains the best source for vulnerability data.