Una falla en la syscall de desinicialización de dispositivos permite a threads no privilegiados ejecutar código arbitrario en modo supervisor, rompiendo por completo el aislamiento de userspace.
El kernel Zephyr RTOS acaba de parchear CVE-2026-19575, una vulnerabilidad clasificada como HIGH por el NVD que permite a un proceso en modo usuario escalar privilegios hasta ejecución arbitraria de código en modo supervisor. El defecto reside en la función z_vrfy_device_deinit() del archivo kernel/device.c, donde la validación del argumento dev utiliza K_SYSCALL_OBJ_INIT(dev, K_OBJ_ANY) — una comprobación que verifica únicamente que el puntero apunte a algún objeto kernel sobre el cual el thread tenga permisos, sin validar jamás el tipo real del objeto. La consecuencia directa: un atacante puede pasar un objeto de stack de thread cuya memoria es escribible desde modo usuario, forzando al kernel a interpretar bytes controlados por el atacante como si fueran una estructura struct device legítima.
Cómo la omisión de tipo convierte memoria de usuario en punteros de función del kernel
La función k_object_validate() implementa un atajo cuando el tipo solicitado es K_OBJ_ANY: omite por completo la comparación de tipos y se limita a verificar que el objeto exista en la tabla de permisos del thread. En el caso de z_vrfy_device_deinit(), esto significa que un atacante puede obtener un objeto de stack de thread — ya sea mediante la syscall k_thread_stack_alloc() o a través de un K_THREAD_STACK definido estáticamente que le fue otorgado para crear un thread hijo — y pasarlo como argumento dev. Dado que la memoria de respaldo de ese stack es escribible desde modo usuario, el atacante controla cada byte que z_impl_device_deinit() va a interpretar como campos de la estructura device.
La implementación z_impl_device_deinit() desreferencia un puntero de estado leído directamente del objeto, llama al puntero de función almacenado en ops.deinit, y en caso de éxito escribe nuevamente a través del puntero de estado. El resultado es una llamada indirecta a una dirección arbitraria ejecutada en modo supervisor, más una lectura arbitraria de memoria kernel y una escritura de un byte. Un exploit preciso entrega ejecución completa de código en kernel; un intento menos cuidadoso provoca un fallo en modo supervisor y el crash del sistema. Las syscalls hermanas z_vrfy_device_init() y z_vrfy_device_is_ready() ya utilizaban K_OBJ_DRIVER_ANY y nunca fueron vulnerables — la inconsistencia en la validación quedó limitada exclusivamente a la ruta de desinicialización.
Exposición condicionada a dos opciones de configuración simultáneas
El defecto solo es alcanzable en builds que habilitan CONFIG_USERSPACE y CONFIG_DEVICE_DEINIT_SUPPORT al mismo tiempo. Con el soporte de desinicialización deshabilitado, z_impl_device_deinit() retorna -ENOTSUP sin desreferenciar el puntero, neutralizando la vulnerabilidad por completo. En las ramas v4.2.x y v4.3.x de Zephyr, CONFIG_DEVICE_DEINIT_SUPPORT estaba habilitado por defecto, lo que significa que cada build con CONFIG_USERSPACE de esas versiones quedó expuesta a menos que el desarrollador deshabilitara explícitamente la opción. Desde v4.4.0, CONFIG_DEVICE_DEINIT_SUPPORT pasó a ser opt-in sin selección por defecto ni dependencias de subsistemas del árbol oficial, reduciendo drásticamente la superficie de exposición en nuevas implementaciones.
La línea v4.2 ya no recibe mantenimiento ni backports, dejando a cualquier deployment en producción sobre esa rama sin parche oficial disponible. El fix aplicado en las ramas mantenidas cambia la validación del objeto a K_OBJ_DRIVER_ANY, que restringe el argumento al rango de tipos de objetos driver generados en tiempo de compilación (K_OBJ_DRIVER_FIRST..K_OBJ_DRIVER_LAST) — las instancias reales de struct device colocadas por el linker — garantizando que los campos state y ops.deinit estén bajo control exclusivo del kernel.
Impacto en dispositivos IoT y edge de América Latina con Zephyr en producción
Zephyr RTOS es el kernel de referencia para dispositivos IoT certificados bajo el paraguas de la Linux Foundation, con adopción creciente en medidores inteligentes, gateways industriales y nodos edge de redes LoRaWAN desplegados en Brasil, México y Argentina. La combinación de CONFIG_USERSPACE — utilizada para aislar aplicaciones de terceros en dispositivos compartidos — y CONFIG_DEVICE_DEINIT_SUPPORT — habilitada por defecto en v4.2.x y v4.3.x — es común en arquitecturas que permiten carga dinámica de módulos o ejecución de código no confiable en el mismo hardware que firmware crítico. Un atacante con acceso a la interfaz de aplicación de usuario en uno de estos dispositivos puede explotar CVE-2026-19575 para ejecutar código en modo supervisor, comprometiendo la cadena de confianza completa del dispositivo y potencialmente pivotando hacia la red backend si el nodo actúa como gateway.
La ausencia de backport para v4.2 plantea un problema de gestión de ciclo de vida para fabricantes que desplegaron dispositivos basados en esa rama y no tienen capacidad de actualización OTA o cuyos contratos de soporte ya expiraron. En sectores como utilities y agricultura de precisión — donde el reemplazo físico de nodos distribuidos en campo tiene costos prohibitivos — la mitigación pasa por deshabilitar CONFIG_DEVICE_DEINIT_SUPPORT mediante recompilación del firmware, asumiendo que la funcionalidad de desinicialización de dispositivos no es crítica para la operación del sistema. Para deployments en v4.3.x con soporte activo, la actualización al último punto release con el parche aplicado es directa; para v4.4.x, la exposición es residual y limitada a builds que habilitaron explícitamente la opción vulnerable.
Nuestro análisis
CVE-2026-19575 es un caso de manual sobre cómo una inconsistencia menor en validación de tipos — usar K_OBJ_ANY en lugar de K_OBJ_DRIVER_ANY — puede convertirse en una primitiva de ejecución arbitraria de código cuando el contexto de llamada permite al atacante controlar la memoria subyacente del objeto validado. El hecho de que las syscalls hermanas ya utilizaran la validación correcta sugiere que el defecto fue introducido por omisión en la implementación de z_vrfy_device_deinit(), no por un diseño arquitectónico defectuoso del sistema de validación de objetos de Zephyr. La dependencia de dos opciones de configuración simultáneas para la explotabilidad — CONFIG_USERSPACE y CONFIG_DEVICE_DEINIT_SUPPORT — actuó como mitigación parcial, pero el hecho de que CONFIG_DEVICE_DEINIT_SUPPORT estuviera habilitado por defecto en dos ramas de release consecutivas amplificó la exposición real en el campo.
La decisión de no mantener v4.2 deja a un segmento del ecosistema IoT en una posición difícil: dispositivos en producción sin ruta de actualización formal y con una vulnerabilidad de escalada de privilegios documentada públicamente. Para la región, donde el costo de reemplazo de hardware desplegado en infraestructura crítica puede ser inviable, esto refuerza la necesidad de políticas de ciclo de vida de firmware más largas en contratos de adquisición de dispositivos IoT, especialmente cuando se trata de kernels de código abierto cuyo soporte depende de la comunidad upstream. ¿Cuántos deployments en campo van a descubrir que están corriendo v4.2 recién cuando un exploit público empiece a circular en foros de seguridad embebida?