Linus Torvalds ha retirado definitivamente las funciones __get_user() y __put_user() de la arquitectura x86 durante el desarrollo de Linux 7.4. La decisión, registrada en el repositorio oficial de Git del kernel, cierra una brecha de seguridad que arrastraba el sistema desde hace décadas: estos mecanismos nunca comprobaban si la dirección de memoria solicitada pertenecía realmente al usuario ni si su rango era seguro.
Os explicamos qué cambia exactamente: el commit que Torvalds ha subido al árbol de desarrollo de Linux 7.4 confirma que estas rutinas, empleadas durante décadas para transferir datos sencillos entre el espacio de usuario y el núcleo, ya no son la opción correcta. Torvalds ha incorporado nuevas interfaces de acceso a memoria y ha recurrido a herramientas de inteligencia artificial para migrar el código restante, cerrando un asunto que, en sus propias palabras, debería haberse resuelto hace años.
Qué funciones elimina Torvalds en Linux
La retirada afecta al apartado de seguridad de la arquitectura x86 y queda documentada en el repositorio oficial de Git del kernel, donde se detalla la fusión de la rama que elimina estas llamadas de forma definitiva.
«Esto era algo que hacía mucha falta», ha escrito Torvalds en el mensaje del commit. Para nosotros, la diferencia entre estas funciones y sus versiones seguras era mínima a simple vista, un doble guion bajo en el nombre, pero en la práctica suponía un salto enorme en el nivel de confianza que el núcleo depositaba en cada llamada: las versiones obsoletas no verificaban si la dirección solicitada era válida. Torvalds considera que estas funciones son completamente obsoletas y que, cuando se utilizan mal (que es prácticamente en todos los casos), resultan más lentas e inseguras. La eliminación afecta al código genérico y cierra la interfaz completa en x86, aunque otras arquitecturas mantienen particularidades distintas, como veremos más adelante.
Por qué esas funciones eran un riesgo de seguridad
El problema de fondo era la falta de validación. A diferencia de sus homólogas sin doble guion bajo, estas funciones no comprobaban si la dirección de memoria solicitada pertenecía realmente al usuario ni si su rango era seguro, lo que las convertía en un vector de riesgo dentro del núcleo del sistema.
«Y cuando se usan mal, es decir, prácticamente en todos los casos, no solo son más lentas que la alternativa adecuada, sino también inseguras porque no comprueban el rango de direcciones del usuario», ha explicado Torvalds. Para entender este matiz conviene repasar cómo se organiza la memoria del sistema y qué diferencia exactamente a estas variantes de las funciones seguras.
El sistema operativo divide su trabajo en dos áreas bien separadas: el espacio de usuario, donde se ejecutan las aplicaciones normales (navegadores, procesadores de texto, etc.), y el espacio del kernel, la zona con privilegios que gestiona el hardware directamente. Cuando un programa necesita intercambiar información con el núcleo, el sistema debe copiar variables entre ambos espacios de forma controlada.
Las funciones get_user() y put_user() realizan esa copia de datos, desde el espacio de usuario hacia el kernel y viceversa, incluyendo las comprobaciones de seguridad necesarias. El doble guion bajo de __get_user() y __put_user() marcaba precisamente una versión que omitía esa validación de rango y propiedad de la dirección, asumiendo que el programador ya había comprobado el inicio del rango de forma manual para ganar velocidad.
El hardware moderno volvió innecesaria esa optimización
El uso de estas funciones sin verificar estaba justificado por el rendimiento en su momento. Los procesadores antiguos necesitaban realizar múltiples accesos continuos a memoria desde un mismo puntero base, así que los programadores ejecutaban una comprobación manual del rango inicial y después recurrían a estas llamadas rápidas para optimizar el código.
El avance del hardware ha cambiado por completo ese cálculo. «Hace años que esto dejó de ser cierto, porque la comprobación de rango ya no representa el verdadero coste a día de hoy. El coste real de los accesos de usuario en el hardware moderno es activar y desactivar los propios accesos de usuario en primer lugar», señala Torvalds. En arquitecturas como x86, el procesador ejecuta secuencias de instrucciones específicas cada vez que el núcleo abre y cierra la ventana de acceso a la memoria del usuario, así que el coste real está en conmutar esos estados de protección, no en comprobar el rango. Dicho de otro modo: la optimización que teníamos por buena durante décadas atacaba el problema equivocado, y mantenerla solo añadía riesgo sin aportar la velocidad que prometía en origen.
Qué aportan las nuevas interfaces
La eliminación de las funciones obsoletas ha sido posible gracias a las interfaces que ha desarrollado Thomas Gleixner, otro de los desarrolladores veteranos del kernel. Sus nuevas interfaces con ámbito permiten abrir la ventana de acceso a la memoria del usuario una sola vez, de forma segura, en lugar de activar y desactivar la protección en cada operación.
Este enfoque agrupa las lecturas y escrituras dentro de un mismo bloque protegido: el núcleo conmuta los estados de protección al principio y al final de ese bloque, en vez de hacerlo en cada acceso individual. Reduce así el número de transiciones de protección que debe ejecutar el procesador, que es precisamente el coste que señalaba Torvalds como el verdadero cuello de botella del acceso a memoria en el hardware actual. Para nosotros, como usuarios del sistema, el cambio pasa inadvertido, pero para quien mantiene el kernel supone sustituir un mecanismo pensado para procesadores de hace más de una década por otro ajustado a cómo funciona realmente el hardware moderno.
Torvalds usa la IA para reemplazar el código obsoleto
Migrar a mano cada uso de estas funciones en todo el árbol de código de Linux habría supuesto una tarea enorme, repartida en cientos de archivos distintos del núcleo. Torvalds ha reconocido que recurrió a Claude Code, una herramienta de inteligencia artificial, para reemplazar de forma automática el código obsoleto que quedaba disperso por el sistema.
La tarea consistía en localizar cada llamada a las funciones retiradas y sustituirla por la alternativa segura correspondiente, un trabajo repetitivo que se presta bien a la automatización porque el patrón de sustitución es el mismo en todos los casos. Torvalds ha revisado el resultado antes de integrarlo en el árbol principal, de modo que la lógica de fondo del sistema siguió bajo su control pese a que gran parte del trabajo mecánico lo hiciera la herramienta de IA. Es uno de los primeros cambios de calado en el kernel en los que Torvalds admite abiertamente haber usado este tipo de asistencia para un proceso de limpieza de código a esta escala.
Cambios para usuarios y desarrolladores de Linux
El alcance de este cambio depende de la arquitectura y del papel de cada persona dentro del ecosistema Linux. En ARM64, las funciones __get_user() y __put_user() ya eran idénticas a sus versiones seguras, así que el tráfico se enviaba directamente a esas implementaciones y nunca arrastraron el mismo riesgo que en x86.
Los desarrolladores que trabajen con código genérico o específico de x86 sí deberán revisar que sus módulos no dependan de las funciones retiradas y migrar, en su caso, a las nuevas interfaces con ámbito que ha introducido Gleixner. Para quien simplemente instala una distribución, el cambio no se nota en el uso diario del equipo: no hay nueva opción que configurar ni interfaz visible. Lo que gana el sistema es un núcleo con menos superficie de ataque en la gestión de memoria, algo que no se ve pero reduce los vectores con los que un fallo de programación podría convertirse en un problema de seguridad real.
La eliminación de estas funciones llega mientras Linux 7.4 continúa en fase de desarrollo. Tocar cientos de archivos y miles de líneas de código, aunque sea de forma automatizada, conlleva siempre el riesgo de introducir alguna regresión que no aparezca hasta que el código circule por más configuraciones de hardware.
