Project Zero publica MAccConc, herramientas para reproducir carreras en el kernel
El conjunto rastrea los accesos a memoria de varios hilos en el kernel de Linux y fuerza el intercalado que dispara el fallo, en lugar de esperar a que aparezca por casualidad

Reproducir una condición de carrera es bastante más difícil que detectarla. El intercalado de hilos tiene que ser el correcto, y eso atasca las tres tareas habituales: confirmar un candidato a fallo, escribir un test de regresión que se dispare siempre, o dejar que un fuzzer explore rutas que solo se ejecutan cuando hay concurrencia de por medio. Google Project Zero ha publicado MAccConc, un conjunto de herramientas para el kernel de Linux que automatiza esa parte.
Qué hace
El método clásico es leer el código, sospechar de un sitio concreto y recompilar el kernel metiendo llamadas a mdelay() condicionadas al hilo que se está ejecutando hasta que el fallo parece. En plataformas con DTrace, como macOS o Windows, se puede hacer algo parecido con probes que invocan a chill(), aunque DTrace solo engancha en fronteras de funciones no inline o en puntos de traza explícitos, no en cada instrucción. Es lento y se va en prueba y error.
MAccConc ataca el problema instrumentando los accesos a memoria. Registra lecturas y escrituras de cada hilo y busca pares que puedan interactuar: dos accesos de hilos distintos que solapen en memoria y donde al menos uno sea escritura. Con eso, la herramienta prueba automáticamente todos los intercalados A-B-A de un caso de test, y además trae una interfaz de terminal y una GUI para explorarlos a mano.
La instrumentación se apoya en ASAN en modo outline (el flag asan-instrumentation-with-call-threshold=0, CONFIG_KASAN_OUTLINE en el kernel), que genera una llamada a función por cada acceso. Con ese gancho, el kernel alimenta los datos a espacio de usuario a través de KCOV en lugar de ftrace; el autor eligió KCOV por su representación más simple en memoria de la traza, por ser instrumentación estática siempre activa y por soportar eventos de mayor frecuencia. Un detalle de implementación: los parches del kernel desactivan con el flag asan-opt-same-temp la optimización del compilador que fusiona llamadas a helpers consecutivas, para tener un callback por acceso.
De dónde viene
El diseño se apoya en ideas parecidas a las de SKI, aunque con otra implementación: SKI graba los accesos y controla el planificador de vCPUs con un QEMU parcheado en modo TCG, tirando de instantáneas de la máquina virtual para recorrer intercalados. MAccConc recoge el relevo conceptual y lo lleva al kernel. El proyecto nació de conversaciones con Ned Williamson y su sockfuzzer, que explora bugs de concurrencia con un planificador propio.
La parte del kernel está pensada también para descubrir condiciones de carrera mediante fuzzing, pero el tooling de espacio de usuario para eso todavía no está. Sí está la intención de aprovechar que todo el registro vive en el kernel para poder probar sobre hardware real en vez de dentro de una máquina virtual.
Para quien mantiene código concurrente, la utilidad inmediata está en los tests de regresión. Cuando se arregla una carrera, casi nunca hay forma de dejar cubierto que vuelva a aparecer; como mucho, un diagrama ASCII en el commit con los hilos y los accesos implicados. Esta herramienta apunta justo a esa parte del ciclo.


