
El código de ptrace en Linux virtualiza el acceso a los registros de depuración, y el código de virtualización tiene un manejo de errores incorrecto. Esto significa que si escribes un valor ilegal en, por ejemplo, DR0, el estado interno del seguimiento de puntos de interrupción del kernel puede corromperse a pesar de que la llamada a ptrace() devolverá -EINVAL.
Por ejemplo, puedes encontrar la dirección de do_debug en /proc/kallsyms en un kernel x86 y pasar esa dirección al PoC adjunto. Sospecho que otras arquitecturas distintas de x86 también están afectadas, pero no he intentado explotarlo. El bug en sí está repartido por todo el kernel, en código genérico y de arquitectura.
No he encontrado una forma obvia de escalar privilegios usando este bug, pero podría existir. Por ejemplo, es plausible que usar este bug para apuntar al manejador NMI de perf pueda desbordar la pila NMI, lo que provocaría varias formas de corrupción. No he intentado analizar el impacto en arquitecturas que no sean x86, ya que solo sé cómo funcionan los puntos de interrupción en x86, pero los efectos del bug podrían ser muy diferentes.
Linus ha corregido en gran medida esto upstream en el commit f67b15037a7a50c57f72e69a6d59941ad90a0f0f. Con ese commit aplicado, el manejo de errores sigue siendo incorrecto, pero el defecto resulta en un punto de interrupción deshabilitado en lugar de uno incorrecto.
http://man7.org/linux/man-pages/man2/ptrace.2.html
Ejemplo de uso: $ ./PoC.exe ffffffff81b44400