VM-exit handler interception¶
Hypervisor'ın merkezi dispatch loop'u: her VM-exit'te CPU bir exit reason saklar ve handler, guest'i devam ettirmeden önce trap edilen instruction/event'i emüle etmek için bunun üzerinde switch yapar — tüm guest→host interception'ın yaşadığı boğaz noktası.
Mechanism¶
Note
Bir guest, VMCS/VMCB'nin intercepted olarak işaretlediği bir eylemi gerçekleştirdiğinde (ör.
CPUID, RDMSR/WRMSR, MOV CR, IN/OUT, VMCALL, EPT violation, exception), CPU bir
VM-exit yapar: guest state'i control structure'a kaydeder, host state'i yükler ve hypervisor'ı
kendi host RIP'inde devam ettirir. Invariant: hardware, hypervisor'a tek bir exit reason alanı
artı qualification/exit info verir ve hypervisor, VMRESUME/VMLAUNCH'tan önce etkiyi tamamen
emüle edip guest RIP'i ilerletmelidir. Bu dispatch, her interception kararının verildiği yerdir;
buradaki doğruluk isolation boundary'dir — yanlış ele alınan bir exit (yanlış RIP ilerletme, exit
qualification üzerinde eksik bounds check, emülasyon bug'ı), tam olarak bir guest-to-host escape'e
dönüşen sınıftır.
Walkthrough¶
Public referans: wbenny/hvpp'nin handler tasarımı. Kavramsal yapı:
- Intercept'leri configure et VMCS/VMCB execution control'leri ve bitmap'lerinde (MSR bitmap, I/O bitmap, exception bitmap), hangi event'lerin exit edeceğini seçmek için.
- Exit reason üzerinde dispatch et. hvpp,
vmexit_passthrough_handlergibi implementasyonlarla birvmexit_handlerbase'i kullanır; handler exit reason'ı okur ve reason-başına rutinlere yönlendirir:switch (exit_reason) { case CPUID: emulate_cpuid(); break; case MSR_READ: emulate_rdmsr(); break; case MSR_WRITE: emulate_wrmsr(); break; case CR_ACCESS: emulate_mov_cr(); break; case IO_INSTR: emulate_io(); break; case VMCALL: handle_hypercall(); break; case EPT_VIOLATION:handle_ept_violation(); break; ... } - Emüle et + (yalnızca instruction-based exit'lerde) RIP'i ilerlet trap edilen instruction
length kadar, sonra
VMRESUME. Dikkat: RIP ilerletme yalnızca instruction-based exit'ler için geçerlidir (CPUID, RDMSR/WRMSR, MOV CR, IN/OUT, VMCALL). Yukarıdaki dispatch switch'inde listelenen EPT violation ve exception exit'leri bu kategoride değildir; bunlarda RIP ilerletilmez — faulting instruction retire olmamıştır; handler ihlal eden koşulu (ör. EPT permission) gevşetir ve döner ki aynı instruction yeniden execute olsun (bkz. EPT violation handling). - Bir
vmexit_handler::setup()hook'u, kodun ilk launch'tan önce VMCS'i initialize/modify etmesine izin verir.
Beklenen gözlemlenebilir: her intercepted instruction artık native çalışmak yerine bir VM-exit round-trip'ine (yüzlerce–binlerce cycle) mal olur.
Warning
Dual-use: bu, her VMM'in omurgasıdır — meşru (KVM/hvpp) ve kötü amaçlı (Blue Pill). Handler'lardaki emülasyon bug'ları birincil bir escape surface'idir.
Detection¶
- Timing: per-exit maliyeti guest'ten gözlemlenebilir — bkz. VM-exit latency fingerprinting.
- Fuzzing/audit: dispatch + reason-başına emülatörler, yanlış ele alınan exit'leri bulmak için VM-exit injection fuzzing ve hypercall fuzzing'in hedefidir.
Mitigation¶
- Hypervisor'ı patch'li tut; intercept'leri minimize et (daha küçük handler surface'i) ve işlem yapmadan önce her guest-controlled alanı (exit qualification, GPA, port/width) validate et.
- Exit'lerden ulaşılan herhangi bir user-space device-emülasyonunu sandbox'la/deprivilege et (sVirt, seccomp) ki bir emülasyon bug'ı sınırlansın.
- Dispatch'i sürekli fuzz'la; her exit-reason yolunu güvenilmez input olarak ele al.
References¶
- wbenny/hvpp — VM-exit handler architecture (README): https://github.com/wbenny/hvpp/blob/master/README.md