ARM Privileged Access Never¶
Armv8.1 PAN:
PSTATE.PAN=1iken, privileged (EL1) data access'leri user-accessible (EL0) memory'ye fault verir — x86 SMAP'in AArch64 karşılığı, ret2usr-tarzı data istismarını block eder.
Mechanism¶
Neden çalışır
Birçok kernel exploit'i, kernel'ı kontrol ettiği bir user-mode adresi okumaya ya da yazmaya kandırır — userspace'te sahte bir structure, kernel'ın doğrudan dereference ettiği bir user buffer. PAN bunu default olarak yasaklar.
PSTATE.PAN = 1 iken, "EL0'da erişilebilir adreslere yapılan privileged read ve
write access'leri" disable edilir; böyle bir access bir Permission fault
raise eder. Meşru user access, PAN'ı kernel'ın uaccess helper'ları üzerinden
geçici olarak clear etmelidir (x86 SMAP'teki stac/clac'in ahlaki karşılığı).
Korumayı otomatik yapmak için, SCTLR_EL1.SPAN (bit 23) re-arming'i kontrol eder: SPAN=0 ile, "EL1'e bir exception alındığında PSTATE.PAN 1'e set edilir", dolayısıyla her kernel entry'si user access reddedilmiş olarak başlar. Invariant şu: kernel, user memory'ye yalnızca açık, denetlenmiş bir window üzerinden dokunabilir — bir EL0 adresine yapılan başıboş herhangi bir EL1 dereference'ı fault verir.
Walkthrough¶
PAN kernel altyapısıdır; onu işletir ve gözlemlersin.
1. Support / enablement durumunu doğrula.
$ zcat /proc/config.gz | grep ARM64_PAN
CONFIG_ARM64_PAN=y
# software fallback for cores without HW PAN:
# CONFIG_ARM64_SW_TTBR0_PAN=y
Kernel, feature'ı boot'ta tespit eder (ARM64_HAS_PAN cpufeature) ve hardware path'ini
ALTERNATIVE üzerinden patch'ler.
2. uaccess window'u (kavramsal kernel path'i). Bir copy_to_user, user access'i PAN
toggle'ları arasına alır:
uaccess_enable_privileged() -> __uaccess_disable_hw_pan() ; clear PSTATE.PAN
... copy bytes to/from the user pointer ...
uaccess_disable_privileged() -> __uaccess_enable_hw_pan() ; set PSTATE.PAN
(Tersine çevrimi not et: user access'i enable etmek, hardware PAN'ı disable eder.)
SET_PSTATE_PAN(1/0), MSR PAN, #imm formunu emit eder.
3. Bir bypass denemesinin fault verdiğini gözlemle. Bir uaccess window'unun dışında attacker tarafından sağlanan bir EL0 adresini dereference eden bir kernel bug'ı — örn. bir userland fake object'e jump etmek ya da onu okumak — attacker-controlled memory'yi sessizce kullanmak yerine EL1'de bir Permission fault alır.
PAN ≠ PXN
PAN, user memory'ye privileged data access'i durdurur; user page'lerinden instruction fetch'i durdurmaz — bu PXN'in işidir. ret2usr'ı tamamen kapatmak için ikisi de gereklidir. Exploit, meşru bir uaccess window'unun içinde çalışabiliyorsa ya da payload'unun kernel-resident bir kopyasına pivot edebiliyorsa PAN bypass edilir.
Mitigation¶
(Residual risk / bypass.) User pointer'larından tamamen kaçınan saldırılar — payload'ları physmap/direct map gibi kernel-mapped memory'ye yerleştirmek — tıpkı SMAP'i atlattıkları gibi PAN'ı da atlatır.
References¶
- LWN. arm64: Add support for Privileged Access Never. — https://lwn.net/Articles/651614/
- torvalds/linux. arch/arm64/include/asm/uaccess.h. — https://github.com/torvalds/linux/blob/master/arch/arm64/include/asm/uaccess.h