Linus Torvalds rara vez escribe código relevante para el kernel de Linux, y por eso la operación del 21 de octubre de 2026 tiene algo de excepción. Ese día fusionó en su propio árbol una serie de 48 parches firmada por él, todos destinados a la versión 7.4 del kernel, que había empezado a recibir cambios dos días antes. Lo que retiran esos parches son las dos primitivas con las que el kernel hurgaba en la memoria de los programas, `__get_user()` y `__put_user()`.
Conviene saber qué hacían. El kernel corre con privilegios y las aplicaciones no, así que cada vez que el primero lee o escribe memoria del segundo pasa por una comprobación de direcciones. Estas dos variantes se saltaban esa comprobación y daban por hecho que la llamada anterior ya la había hecho. El merge toca 50 ficheros, con 689 líneas añadidas y 801 borradas.
El detalle que se pierde en el titular es que no desaparecen las funciones normales, sino la familia con doble guion bajo, la que no verificaba nada y por tanto permitía leer o escribir donde no tocaba. Torvalds lo resume en el mensaje del merge con una frase seca: usadas mal, y según él se usaban mal siempre, eran más lentas y además inseguras. Esa comprobación que ahorraban fue buena práctica durante años, y de ahí que la limpieza llegue con una década de retraso.
Cincuenta ficheros y una rama llamada uaccess-cleanups
El commit de referencia es 22a78a25438d, un merge con el asunto «Merge \_\_{get,put}\_user() removal branch» que Torvalds firmó como autor y como integrador el 21 de octubre de 2026, a las 07:19 de su hora, la de Hawái. La rama se llama uaccess-cleanups y agrupa 48 commits que tocan ARM, powerpc y x86 además de media docena de arquitecturas menores.
El calendario ayuda a situar la maniobra. Linux 7.3 salió el domingo 18 de octubre de 2026, al final de un ciclo de nueve semanas, y el anuncio avisaba de que el lunes abría el periodo de fusión de 7.4 y de que su autor estaría esos días de vacaciones familiares.
¿Qué separa al kernel de la memoria ajena?
Un programa puede pedir al sistema operativo que lea o escriba en cualquier dirección. Si el kernel aceptara sin más un puntero que llega desde el espacio de usuario, una aplicación podría colar la dirección de sus propias estructuras y ganar privilegios. Por eso las funciones normales comprueban antes que el rango cae del lado permitido.
Las variantes con doble guion bajo saltaban ese primer paso. Estaban pensadas para código que ya había validado el rango y quería hacer varias lecturas seguidas sobre la misma base, de modo que el chequeo se pagaba una sola vez. El ahorro dependía de que la validación previa existiera.
El mensaje del merge es explícito sobre lo que pasaba cuando no existía: además de ser más lentas que la vía moderna, no comprobaban el rango de direcciones del usuario. Una interfaz que invita a equivocarse así acaba generando código que compila sin aviso y esconde el fallo hasta que alguien lo explota.
La alternativa moderna agrupa los accesos en bloques con inicio y fin, de forma que el cierre quede garantizado tanto si el camino acaba bien como si acaba en error. Ese es el cambio que hizo posible el resto.
Las cuatro razones que dejaron de valer
El mensaje del merge no se limita a decir que la vieja interfaz sobraba. Repasa los motivos por los que se había usado durante años y explica qué pasó con cada uno de ellos, sin adornos.
| Razón histórica |
Por qué dejó de valer |
Qué se usa en su lugar |
| Rendimiento al leer varias veces desde una misma base |
El coste real no es el chequeo, sino activar y desactivar el acceso |
Bloques con ámbito, como `scoped_user_read_access()` |
| Acceso a un puntero de kernel poco fiable durante el manejo de fallos |
Ya existe un ayudante específico para ese caso |
`get_kernel_nofault()` |
| Evitar el aviso de `might_fault()` en regiones atómicas |
Esa región debe desactivar los fallos de página de forma explícita |
`pagefault_disable()` |
| Punteros que podían ser de kernel o de usuario |
Casi todos esos casos se habían eliminado antes |
Accesos explícitos según el origen |
La primera fila es la más interesante, porque fue el argumento técnico serio a favor de las primitivas durante años. Una comprobación seguida de muchas lecturas sin comprobar generaba código más pequeño y más rápido en máquinas antiguas.
La palabra clave que usa Torvalds es «solía», porque en el hardware actual el gasto real no está en el rango, sino en encender y apagar el acceso al espacio de usuario, que en x86 se hace con las instrucciones STAC y CLAC.
Ahí es donde los bloques con ámbito cambian la economía del asunto. Si el precio se paga al abrir el bloque y no en cada lectura, la variante sin comprobación deja de tener ventaja y solo queda su riesgo. La tercera fila revela un motivo menos confesable, el de código que callaba un aviso del kernel en lugar de arreglar lo que el aviso señalaba.
Un ejemplo convertido por Claude
El origen de la serie fue un parche suelto, no una campaña de limpieza. Torvalds lo escribió como muestra de cómo convertir esas llamadas a la forma moderna, para que otros vieran el patrón y lo copiaran. La muestra prendió y acabó en una serie que toca medio centenar de ficheros.
El empujón definitivo llegó del trabajo ajeno. Thomas Gleixner añadió en octubre de 2025 los bloques de acceso con ámbito, una sintaxis que limpia el acceso al salir del bloque tanto en el camino bueno como en el de error, y que Torvalds cita como lo que elimina cualquier excusa para seguir con las viejas primitivas.
En el mensaje del merge hay una confesión de método: parte del trabajo se hizo con Claude, al que Torvalds describe como un script de coccinelle de lujo, es decir, una herramienta para aplicar un patrón a muchos sitios sin escribirlos uno a uno.
El ciclo 7.3, que llegó el 18 de octubre con FailFS y con mejoras para jugar con poca VRAM según nuestro resumen del lanzamiento, trajo además abundantes contribuciones asistidas por modelos de lenguaje, un detalle que LWN subrayó en su recuento del ciclo.
Cambiar la disciplina individual por un mecanismo que la haga innecesaria se repite en otros proyectos. En el ecosistema de Rust, la cuarentena de dependencias que Cargo activa en Rust 1.100 impone una edad mínima a los paquetes recién publicados para que nadie tenga que vigilar el registro a mano.
x86 se queda sin la interfaz, el resto espera
La retirada completa solo ocurre en una arquitectura. El propio mensaje lo advierte: la serie quita todas las llamadas de ese tipo del código genérico, pero el borrado definitivo de la interfaz se hace en x86, donde la cabecera pierde la mayor parte de sus definiciones y las rutinas en ensamblador se recortan.
En arm64 las dos variantes eran idénticas a las funciones normales, así que no arrastraban el peligro antiguo y no había urgencia. Cualquier arquitectura que use el fichero genérico de acceso a usuario seguirá llamando así a su ayudante interno, y varias conservaban usos heredados que Torvalds no quiso tocar porque no los conoce y no le parecían relevantes.
Ese reparto tiene una consecuencia práctica para quien mire el árbol en las próximas semanas. Las funciones normales siguen ahí y se usan a diario, la interfaz antigua desaparece donde más código la usaba y en el resto el nombre sobrevive como detalle interno.
Lo que la limpieza deja a la vista
El cambio no altera nada para quien use Linux en un portátil o en un servidor, y esa invisibilidad es la medida de su éxito. Lo que se ha ido es una puerta que permitía escribir código inseguro con apariencia de optimización, y con ella el motivo para discutir cada caso concreto durante otra década.
Queda la parte menos lucida del calendario. El merge entró en un periodo de fusión que su propio autor avisó que podría estirarse por vacaciones, y la serie se escribió con ayuda de una herramienta que aplica patrones a escala. La próxima limpieza se parecerá más a eso que a la imagen del mantenedor reescribiendo el kernel a mano.