Intel CET Supervisor Shadow Stack¶
CET shadow stack'lerinin supervisor (ring-0) tarafı: MSR'larda privilege-level başına shadow-stack pointer'ları ve bir kernel ROP girişimini control-protection (#CP) fault'una çeviren korumalı bir return-address kopyası,
CR4.CETile koşullanır.
Mechanism¶
Neden çalışır
Bir shadow stack, her return address'in ikinci, hardware tarafından korunan
bir kopyasını tutarak ROP'u yener: CALL'da CPU return address'i hem normal
stack'e hem de shadow stack'e push'lar ve RET'te onları karşılaştırır —
ikisi farklıysa, processor bir control-protection (#CP) fault'u doğurur.
Supervisor varyantı bu invariant'ı ring 0'a genişletir. Mekanizma
user-mode shadow stack ile aynıdır; fark
enablement ve scope'ta: burada IA32_S_CET + CR4.CET, per-privilege
IA32_PL0..3_SSP ve supervisor busy-bit token'ları (SETSSBSY/CLRSSBSY)
devreye girer, arch_prctl/glibc opt-in yerine OS/hypervisor doğrudan MSR
programlar.
- Supervisor shadow stack'leri, user-mode
IA32_U_CET'in (0x6A0) ring-0 karşılığı olanIA32_S_CETMSR'ı (adres0x6A2) aracılığıyla yapılandırılır. Düşük bit'ler (SH_STK_EN,WR_SHSTK_EN), supervisor mode için shadow-stack enforcement'ını veWRSSinstruction'ını etkinleştirir. - Ring 0'ın birkaç privilege level'i olduğu ve SSP'nin ring geçişlerinde
değiştirilmesi gerektiği için, mimari privilege başına shadow-stack pointer
MSR'ları sağlar:
IA32_PL0_SSP,IA32_PL1_SSP,IA32_PL2_SSPveIA32_PL3_SSP. CPL'yi 0'a yükselten bir geçişte, processor SSP'yiIA32_PL0_SSP'den yükler. - Ana etkinleştirme
CR4.CETbit'idir (bit 23).CR4.CET=0ile hiçbir CET enforcement'ı olmaz; OS bunu*_CETMSR'larını programlamadan önce set eder. Shadow-stack page'leri özel bir "shadow stack" memory type'ı taşır — sıradanMOVstore'ları fault verir, onlara yalnızca call/return makinesi veWRSS/INCSSP/RSTORSSPdokunur. - Supervisor shadow stack'leri, stack base'indeki bir supervisor token'ında bir
busy bit kullanır:
SETSSBSYbir shadow stack'i aktif işaretler (busy set eder),CLRSSBSYonu serbest bırakır veRSTORSSPbir restore token aracılığıyla bir shadow stack'e geçer. Bu, iki logical processor'ın tek bir shadow stack'i paylaşmasını önler.
Invariant: RET'in okuduğu return hedefi, attacker'ın forge edemeyeceği
bellekte yaşar — ring 0'da bile. Kaydedilmiş bir return address'i yeniden yazan
bir kernel stack overflow shadow kopyasını el değmemiş bırakır, dolayısıyla
uyuşmazlık kontrolü yönlendirmek yerine fault verir.
Walkthrough¶
1. Mimari yapı taşlarını doğrula. CET desteği CR4.CET (bit 23 / mask
0x800000) ile duyurulur; yazılım etkinleştirmeden önce bunu kontrol eder:
; pseudo-check used by an OS / hypervisor
mov rax, cr4
test rax, 0x800000 ; CR4.CET — is CET enabled?
jz cet_not_enabled
2. Supervisor SSP bir GPR'da değil, MSR'larda yaşar. Yazılım canlı SSP'yi
RDSSPQ ile okur ve PL başına pointer'ları MSR'lar aracılığıyla programlar:
IA32_S_CET = 0x6A2 ; supervisor CET config (SH_STK_EN, WR_SHSTK_EN, ENDBR_EN ...)
IA32_PL0_SSP = 0x6A4 ; SSP loaded on transition to CPL 0
IA32_PL1_SSP = 0x6A5
IA32_PL2_SSP = 0x6A6
IA32_PL3_SSP = 0x6A7
3. Supervisor shadow stack'leri kur ve aralarında geçiş yap, kısıtlanmış
instruction'larla (hiçbir düz MOV SSP'ye yazamaz):
SETSSBSY ; set busy bit in supervisor shadow-stack token -> activate
RSTORSSP mem ; switch to another shadow stack via its restore token
CLRSSBSY mem ; clear busy bit -> release the shadow stack
4. Bir kernel ROP girişiminde fault'u gözlemle. Normal kernel stack'indeki
kaydedilmiş bir return address'i overwrite et; RET'te shadow kopyası hâlâ gerçek
caller'ı tutar, ikisi uyuşmaz ve CPU gadget'a atlamak yerine bir control-protection
(#CP) fault'u teslim eder.
Linux kernel shadow stack'i değil, kernel IBT'yi destekler
Linux 64-bit kernel'i yalnızca userspace shadow stack artı kernel IBT
implemente eder: kernel belgelerine göre, "Bugün 64-bit kernel'de yalnızca
userspace shadow stack ve kernel IBT destekleniyor." Supervisor shadow
stack'leri en belirgin biçimde diğer OS'lerde görülür — örn. IA32_PL0_SSP'nin
ring-0 shadow stack'ini tuttuğu ve supervisor token'larının geçişi koruduğu
Windows kernel-mode shadow stack'leri.
Mitigation¶
(Artık risk / hâlâ neler geçer.) Supervisor shadow stack yalnızca backward
edge'leri (kernel return'leri) korur. Forward-edge hijack'leri — bir indirect
CALL/JMP hedefini bozma, JOP veya COOP tarzı data-only call-site reuse —
etkilenmez ve Indirect Branch Tracking ya
da FineIBT gibi daha ince CFI gerektirir. Kernel IBT sevk eden ama
kernel shadow stack sevk etmeyen bir platform ring-0 return'lerini korumasız bırakır.
References¶
- The Linux Kernel. Control-flow Enforcement Technology (CET) Shadow Stack. — https://docs.kernel.org/next/x86/shstk.html
- Connor McGarr. Exploit Development: Investigating Kernel Mode Shadow Stacks on Windows. — https://connormcgarr.github.io/km-shadow-stacks/
- Wikipedia. Indirect branch tracking. — https://en.wikipedia.org/wiki/Indirect_branch_tracking