EPT violation handling¶
Bir guest erişimi second-level (EPT) translation'daki host-owned Read/Write/Execute permission bit'lerini ihlal ettiğinde tetiklenen hypervisor VM-exit path'i — her SLAT-tabanlı stealth, introspection ve integrity primitive'inin üzerine kurulduğu dispatch noktası.
Mechanism¶
Note
Extended Page Tables (EPT) ile CPU ikinci bir translation yapar:
guest-physical address'ler (GPA), host-owned EPT paging yapıları boyunca,
destekleyen host frame'i üzerinde bağımsız Read (bit 0), Write (bit 1) ve
Execute (bit 2) permission bit'leri taşıyan bir EPT leaf entry'sine kadar walk
edilir. Guest bu bit'leri göremez ya da değiştiremez. Bir guest erişimine EPT
leaf'i izin vermediğinde — R=0 bir page'in data read'i, W=0 bir page'in write'ı
ya da X=0 bir page'in instruction fetch'i — CPU bir guest #PF teslim etmez;
bunun yerine basic exit reason'ı "EPT violation" olan bir VM exit alır.
Bunun temiz bir izolasyon primitive'i olmasının nedeni, burada zorlanan permission bit'lerinin guest'in değil, host'un translation katmanına ait olmasıdır. Guest'in kendi page table'ları bir page'i present, writable ve executable işaretleyebilir ve EPT katmanı izin vermiyorsa erişim yine de trap eder — ve şeffaf biçimde, guest bir fault gözlemlemeden trap eder. Bu asimetri tam olarak EPT'yi stealth hooking, EPT split'leri ve introspection için zemin yapan şeydir: host, guest page'in özel olduğunu hiç öğrenmeden bir erişimden haberdar olmak için bir permission'ı geri alabilir.
Exit'te Exit Qualification alanı violation'ın neden oluştuğunu encode eder:
- Bit 0 — erişim bir data read'di.
- Bit 1 — erişim bir data write'tı.
- Bit 2 — erişim bir instruction fetch'ti (execute).
- Bit 3–5 — GPA için EPT leaf'inin mevcut R/W/X permission'ları.
- Bit 7 — faulting GPA bir paging-yapısı erişimi yerine bir guest-linear adresin translation'ı ise (yani normal bir data/code erişimi) set'tir.
- Bit 8 — guest-linear-address geçerliliği (bir GVA'nın hiç dahil olup olmadığı).
Faulting guest-physical address'in kendisi VMCS GUEST_PHYSICAL_ADDRESS alanından
okunur; bit 7/8 geçerli bir GVA gösterdiğinde GUEST_LINEAR_ADDRESS da doldurulur.
İlgili ama farklı bir exit olan EPT misconfiguration, EPT entry'sinin kendisi
malformed olduğunda (reserved bit'ler, R'siz W vb.) tetiklenir — bu bir konfigürasyon
hatasıdır, bir access-permission olayı değil.
Walkthrough¶
Temsili handler iskeleti (kavramsal, Hypervisor-From-Scratch / HyperDbg tarzı koda dayalı):
case EXIT_REASON_EPT_VIOLATION: {
u64 gpa, qual;
__vmx_vmread(GUEST_PHYSICAL_ADDRESS, &gpa);
__vmx_vmread(EXIT_QUALIFICATION, &qual);
bool read = qual & (1 << 0);
bool write = qual & (1 << 1);
bool execute = qual & (1 << 2);
pEptEntry entry = EptGetPml1Entry(gpa); // locate the leaf for this GPA
if (execute && entry->ExecuteAccess == 0) {
// e.g. monitored code page: grant X, then re-run the faulting insn
entry->ExecuteAccess = 1;
InveptSingleContext(); // flush cached EPT translations
// do NOT advance guest RIP — let the instruction retire normally
}
// ... read/write cases handled symmetrically ...
break;
}
İki detay yük taşır:
- RIP ilerletilmez. Çoğu VM exit'in aksine, faulting instruction retire olmamıştır; handler ihlal eden permission'ı gevşetir (ya da page'i swap eder) ve döner ki aynı instruction yeniden execute olsun ve artık başarılı olsun.
- INVEPT. CPU, GPA→HPA translation'larını (ve permission'larını) cache'lediği
için, bir EPT entry'sini
INVEPTolmadan değiştirmek stale bir cached mapping bırakabilir. Handler, bir entry'yi edit ettikten sonra EPT context'ini invalidate eder.
Warning
Bir permission'ı kalıcı vermek monitor'ü etkisiz kılar. Stealth primitive'leri bunun yerine permission'ı yalnızca bir instruction için verir ve sonra yeniden geri alır — tipik olarak Monitor Trap Flag (MTF)'i arm ederek; böylece yeniden execute edilen tek instruction retire olduktan sonra bir VM exit tetiklenir ve o noktada handler kısıtlayıcı permission'ları geri yükler. Bkz. EPT-switch single-step.
Gözlemlenebilir exit-qualification decoding'i
[vmexit] reason=EPT_VIOLATION
GUEST_PHYSICAL_ADDRESS = 0x1f3a000
EXIT_QUALIFICATION = 0x181
bit0 read = 1 <- data read attempted
bit1 write = 0
bit2 exec = 0
bit7 gva-xlat= 1 <- GPA is translation of a guest-linear address
bit8 gla-vld = 1
=> guest performed a data READ of a page whose EPT R bit is 0
Detection¶
- Bir guest page'lerin trap'lendiğini çıkarsayabilir: relax-execute-sonra-MTF-restore ile handle edilen bir EPT violation, etkilenen erişimin latency'sini şişirir ve bir timing side channel verir. Şüphelenilen page'lerin read/fetch'lerini timing'leyen sıkı döngüler monitör edilen region'ları açığa çıkarabilir.
- Host/defender tarafından, EPT violation'ları authoritative event akışıdır: code page'lerinde beklenmeyen violation'lar ya da asimetrik R/W/X leaf permission'ları, bir SLAT-tabanlı hook'un ya da introspection katmanının kurulu olduğuna işaret eder.
- Log'lardaki EPT misconfiguration exit'leri, sıradan access fault'lar yerine malformed (muhtemelen saldırgan tarafından hazırlanmış) EPT entry'lerine işaret eder.
Mitigation¶
- EPT/SLAT konfigürasyonu yalnızca trusted hypervisor'a ait olmalıdır; guest state bir EPT leaf'inin hangi permission'ları taşıdığını asla etkilememelidir.
- Handler-driven permission flip'lerini rate-limit'le ya da denetle; tek bir GPA'da bir EPT violation seli, hot bir page'e karşı kurulmuş bir hook'un güçlü bir sinyalidir.
- Nested virtualization altında, L0 hypervisor L1'in EPT permission'larını ve EPT-violation semantiğini sadakatle shadow'lamalıdır, aksi halde nested bir guest kendi izolasyonu hakkında yanıltılabilir.
- Permission gevşetmeyi MTF-tabanlı single-step restoration ile eşleştir (bir page'i asla kalıcı olarak permissive bırakma) ki monitör edilen özellik yeniden execute edilen instruction boyunca korunsun.
References¶
- Hypervisor From Scratch – Part 7: Using EPT & Page-Level Monitoring Features (Rayanfam Blog)
- Design of !epthook — HyperDbg Documentation
- Intel 64 and IA-32 Architectures SDM, Vol. 3C, "VM Exits / EPT Violations" (Exit Qualification for EPT violations). (referenced indirectly via the above write-ups; not fetched directly here)