Investigadores de seguridad en Calif han demostrado una vulnerabilidad de escalada de privilegios locales (LPE) en OpenBSD que surge de un error con casi cuatro décadas de antigüedad. El fallo se originó en el código fuente original de BSD, donde un contador de adjunción de memoria compartida se definió como un short de 16 bits con signo. Debido a que este contador es con signo, realizar repetidamente un fork de un proceso con registros de adjunción de memoria compartida puede empujar el valor más allá de su límite máximo de 32,767, provocando que se envuelva en un valor negativo. Este desbordamiento de enteros, combinado con una escritura fuera de límites independiente en el kernel, permite a un atacante obtener privilegios de root.

Esta imagen representa el proyecto de investigación principal descrito en el artículo sobre el error del kernel de OpenBSD.
El mecanismo de explotación se basa en una secuencia compleja de operaciones para evadir mitigaciones de seguridad modernas como KARL, SMAP y SMEP. Los investigadores primero envuelven el conteo de adjunción de memoria compartida a un valor negativo (-32,643) mediante el fork de 259 procesos. Luego realizan un 'heap grooming', utilizando métricas de `sysctl(KERN_MALLOCSTATS)` para rastrear las asignaciones de memoria. Al ganar una condición de carrera durante una operación `IPC_RMID`, los investigadores pudieron adjuntar un segmento de memoria compartida con confusión de tamaño. Esto activó una escritura condicional fuera de límites que sobrescribió los campos de membresía del kernel. Finalmente, al cerrar un socket para atravesar los miembros del grupo, activaron decrementos atómicos que modificaron el mapeo autorreferencial de la Entrada de Tabla de Páginas (PTE), cambiándola de modo accesible por el usuario a modo de supervisor, permitiendo la ejecución de código en el kernel.
Si bien las vulnerabilidades fueron abordadas en las erratas 026 y 018 de OpenBSD, los investigadores destacaron varios riesgos arquitectónicos restantes. Señalaron que, aunque el sistema KARL de OpenBSD aleatoriza las direcciones de funciones y datos, los asignadores de memoria del kernel siguen siendo deterministas. Esto significa que las asignaciones tempranas durante el arranque aterrizan consistentemente en ubicaciones predecibles, lo que las convierte en objetivos ideales para sobrescribir punteros de función, como los manejadores ioctl de `lo0` y `enc0`. Para mitigar estos riesgos, los investigadores sugirieron varias mejoras: implementar 'safe-unlinking' para verificar las invariantes de listas doblemente enlazadas, aleatorizar la dirección de asignación del mapa PTE autorreferencial, o hacer que el asignador del kernel sea no determinista aleatorizando tanto la dirección base como el orden de asignación en tiempo de ejecución. También señalaron próximas características del compilador, como 'Alloc Tokens', que podrían aislar las asignaciones que contienen punteros de las que no los contienen para neutralizar clases similares de vulnerabilidades.