Skip to content

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ı:

  1. 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.
  2. Exit reason üzerinde dispatch et. hvpp, vmexit_passthrough_handler gibi implementasyonlarla bir vmexit_handler base'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;
      ...
    }
    
  3. 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).
  4. 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

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