PAC Signing-Oracle Reuse¶
ARM Pointer Authentication'ı bir imzayı forge ederek değil; geçerli imzalanmış pointer'ları reuse ederek — veya doğru ile yanlış PAC'leri ayırt eden microarchitectural bir oracle kurarak — bypass etmeye dair bir bug-class notu.
Mechanism¶
Note
ARM Pointer Authentication (ARMv8.3-A), 64-bit bir pointer'ın boş üst
bitlerinde bir pointer authentication code (PAC) saklar — PARTS yazarları
bunu "a tweakable MAC that can be squeezed into the unused high-order bits of
a pointer" diye tanımlar. PAC üç girdiden hesaplanır (erken
implementasyonlarda QARMA ile): pointer değeri, saldırganın okuyamadığı key
başına bir secret register ve bir modifier (a.k.a. context/tweak, örn.
return address için SP). pac* instruction'ları imzalar; aut*
instruction'ları doğrular ve çıkarır. Security invariant'ı tazelik +
context binding'dir: bir PAC yalnızca bu modifier altında bu pointer
değeri için anlamlıdır. Yayınlanan zayıflık şudur: PA, kullanımlar arası
benzersizliği garanti etmez. Eğer saldırgan, kullanım yerine uyan bir
modifier altında zaten imzalanmış bir pointer ele geçirebilirse, onu olduğu
gibi reuse edebilir — ne key ne forgery. Aalto SSG yazısının dediği gibi:
"if an attacker can use a memory vulnerability to read from the program's
memory, then they can obtain authenticated return addresses that will validate
correctly."
Bu sınıfın altına, ayrı ayrı yayınlanmış iki farklı reuse problemi düşer:
- Same-context signing-oracle reuse (Liljestrand et al., USENIX Security
2019). Modifier M altında imzalanmış geçerli bir
(pointer, PAC)çifti, programın daha sonra aynı M altında authenticate ettiği her yerde replay edilebilir. 16-bit bir PAC ile, makale ayrıca collision'ların birthday bound ile erişilebilir olduğunu belirtir — yollar arasında çakışan bir imzayı zorlamak için "320 attempts on average" mertebesinde. - Speculative PAC oracle — PACMAN (Ravichandran et al., ISCA 2022). İmzalı
bir pointer'ı okumadan bile saldırgan bir PAC'i tahmin edebilir ve
speculative bir
aut+load'un bir microarchitectural iz bırakıp bırakmadığını gözlemleyerek tahminin doğru olup olmadığını, hiç crash etmeden öğrenebilir.
Walkthrough¶
Same-context reuse (PARTS, 2019). Linux'taki stok PA, return address'leri
SP ile key'leyerek imzalar ve tüm function pointer'ları tek bir paylaşılan
modifier altında imzalar. Bu, leak edilmiş, geçerli şekilde imzalanmış herhangi
bir function pointer'ın, aynı modifier'ı kullanan bir call site'ta bir başkasının
yerine konabileceği anlamına gelir — autia/blraa dizisi onu kabul eder. PARTS
bunu, modifier'a bir static type id taşıtarak daraltır: pointer'lar "signed
with type IDs, which limits reuse of signed return addresses within the same
functions and signed function pointers within the same types." Type'lar arası
reuse o zaman verification'da başarısız olur. PARTS, bir type/context içindeki
reuse'u ortadan kaldırmaz — bu artık, kabul edilen sınırlamadır.
Speculative oracle (PACMAN, 2022). PACMAN "takes an existing software bug (memory read/write) and turns it into a more serious exploitation primitive (a pointer authentication bypass)." Bir PACMAN gadget'ının iki speculative parçası vardır:
# conceptual PACMAN gadget (from the paper's description)
if (cond): # mispredicted branch -> speculative window
verified_ptr = aut(guess_ptr) # 1. verify a *guessed* PAC speculatively
load(verified_ptr) # 2. transmit result via a side channel
Verification speculative olarak gerçekleştiği için, "the PAC Oracle must never crash if an incorrect guess is supplied" — yanlış tahminler asla architectural state'e ulaşmaz. Açıklanan PoC, doğru ile yanlış PAC'leri TLB üzerinde bir Prime+Probe ile ayırt etti: doğru bir tahmin speculative load'un ilerlemesine izin verir ve TLB state'ini gözlemlenebilir biçimde bozar. Küçük PAC alanını bu şekilde brute-force etmek, herhangi bir crash sinyali olmadan geçerli bir PAC'i kurtarır.
Detection¶
- Same-context reuse, tasarımı gereği PA'nın kendisine görünmezdir —
aut*kontrolü geçer. Bu yüzden detection primitive'in dışında yaşar: shadow-stack / backward-edge CFI, return-address substitution'ı yakalar; type- veya call-site-granular CFI, forward-edge function-pointer swap'larını yakalar; anormal hacimdeaut-faultBRKexception'ı (PA auth-failure trap'leri) forgery denemelerini işaretleyebilir ama başarılı reuse'u değil. - PACMAN, herhangi bir speculative side-channel saldırısının habercileri
olarak görünür: bir
aut+dependent-load üzerinde mispredict edilmiş branch'lerin sıkı bir loop'u, artı bir TLB/cache Prime+Probe ölçüm loop'u. Tahmin pointer'ları sağlamak için önceden var olan bir memory-corruption bug'ına ihtiyaç duyar, dolayısıyla corruption'ın kendisi daha güvenilir detection yüzeyidir.
Mitigation¶
- Modifier/context'i çeşitlendir. PARTS katkısı — type-tagged modifier'lar — reuse kümesini "herhangi bir pointer"dan "aynı site'ta aynı static type'a sahip pointer'lar"a daraltır. Call-site- veya address-keyed modifier'lar onu daha da azaltır.
- PA'yı CFI / shadow stack ile birleştir. PA tek başına bir değer üzerindeki bir integrity kontrolüdür; onu bir backward-edge shadow stack ve forward-edge kernel CFI ile eşleştirmek, artık kalan same-context reuse penceresini kaldırır.
- Sadece PAC'i değil, bug'ı ele al. PACMAN bir memory R/W primitive'ine ihtiyaç duyar; spatial/temporal safety (örn. MTE) ona dayandığı corruption'ı tanımaz.
- Speculation hardening. PACMAN bir speculative side channel olduğundan,
generic Spectre-tarzı mitigation'lar (
autçevresinde speculation barrier'ları, guarded load'ları maskeleme) oracle'ı kapatır. Sonraki PA varyantları (FPAC /arm-pacbtifault-on-auth-fail) hatalı biraut'u deterministik biçimde fault ettirir; bu da oracle'ın dayandığı sessiz mispredict yolunu kaldırır. Belirli bir silikonun FPAC davranışı bir kaynakta doğrulanmadığı yerde bu son noktayıunverifiedolarak işaretleyin.