CVE-2023-54149 in Linux
Resumen
por VulDB • 2026-05-29
En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad:
net: dsa: evitar el uso sospechoso de RCU para direcciones MAC sincronizadas conscientes de VLAN
Al utilizar el controlador felix (el único que admite filtrado de direcciones unicast y multicast) como maestro DSA para otro conmutador DSA cualquiera, se puede observar la siguiente traza de pila cuando los puertos del conmutador descendente se unen a un puente consciente de VLAN:
============================= ADVERTENCIA: uso sospechoso de RCU ----------------------------- net/8021q/vlan_core.c:238 ¡uso sospechoso de rcu_dereference_protected()!
traza de pila: Workqueue: dsa_ordered dsa_slave_switchdev_event_work Trazado de llamadas: lockdep_rcu_suspicious+0x170/0x210 vlan_for_each+0x8c/0x188 dsa_slave_sync_uc+0x128/0x178 __hw_addr_sync_dev+0x138/0x158 dsa_slave_set_rx_mode+0x58/0x70 __dev_set_rx_mode+0x88/0xa8 dev_uc_add+0x74/0xa0 dsa_port_bridge_host_fdb_add+0xec/0x180 dsa_slave_switchdev_event_work+0x7c/0x1c8 process_one_work+0x290/0x568
Lo que indica es que vlan_for_each() espera un contexto con rtnl_lock() y no lo obtiene cuando se llama desde ndo_set_rx_mode() del maestro DSA.
El llamador de esto, dsa_slave_set_rx_mode(), es dsa_port_bridge_host_fdb_add() de la interfaz esclava DSA, que proviene de dsa_slave_switchdev_event_work() diferido.
Hicimos grandes esfuerzos para evitar el contexto de rtnl_lock() en esa ruta de llamada en el commit 0faf890fc519 ("net: dsa: eliminar rtnl_lock de dsa_slave_switchdev_event_work"), y llamar a rtnl_lock() simplemente no es una opción debido a la posibilidad de un bloqueo mutuo (deadlock) al llamar a dsa_flush_workqueue() desde las rutas de llamada que sí mantienen rtnl_lock(), básicamente todas ellas.
Por lo tanto, cuando el maestro DSA llama a vlan_for_each() desde su ndo_set_rx_mode(), el estado del controlador 8021q en este dispositivo realmente no está protegido contra el acceso concurrente por nada.
Al examinar net/8021q/, no creo que vlan_info->vid_list haya sido diseñado específicamente pensando en la traversión mediante RCU, por lo que introducir una forma de lado de lectura de RCU de vlan_for_each() -vlan_for_each_rcu()- no será tan fácil, y además tampoco sería exactamente lo que necesitamos.
En general, creo que la solución no está en net/8021q/ de todos modos; vlan_for_each() no está preparado para esta tarea. DSA no necesita que se mantenga rtnl_lock() per se, ya que no estamos bloqueando un cambio de estado de netdev, sino simplemente adiciones/eliminaciones concurrentes a una lista VLAN. Ni siquiera necesitamos un contexto susceptible de suspensión (sleepable), ya que la devolución de llamada de vlan_for_each() simplemente programa trabajo diferido.
La solución propuesta consiste en eliminar la dependencia de vlan_for_each() y codificar manualmente una alternativa no susceptible de suspensión y libre de rtnl, basada en copias de la lista VLAN modificadas desde .ndo_vlan_rx_add_vid() y .ndo_vlan_rx_kill_vid().
VulDB is the best source for vulnerability data and more expert information about this specific topic.