Skip to content

Hardware-assisted AddressSanitizer

HWASan (-fsanitize=hwaddress), her pointer'ın kullanılmayan top byte'ında rastgele bir tag ve memory granule başına eşleşen bir tag saklar; böylece bir use-after-free veya overflow, ASan'dan çok daha düşük memory overhead'iyle erişimde yakalanır.

Mechanism

HWASan, AddressSanitizer'a benzer ama Address Tagging üzerine kurulu bir memory-safety aracıdır. AArch64'te Top-Byte-Ignore (TBI) özelliği, yazılımın 64-bit bir pointer'ın en anlamlı 8 bit'inde arbitrary bir değer saklamasına izin verir; CPU dereference ederken o bit'leri görmezden gelir. SPARC ADI ve Arm MTE benzer tagging'i çoğunlukla hardware'de sağlar.

Allocation'da HWASan rastgele bir TS-bit tag (tipik olarak 4 veya 8 bit) seçer, onu pointer'ın top byte'ına yazar ve aynı tag'i object'in her TG-byte granule'ü (tagging granülaritesi, tipik olarak 16 veya 64 byte) için shadow memory'de saklar. Her instrument edilmiş load/store, erişilen granule için shadow tag'i okur ve onu pointer'ın top byte'ı ile karşılaştırır.

Invariant HWASan enforces

Bir memory access yalnızca pointer'ın top byte'ındaki tag, erişilen granule için saklanan tag'e eşitse geçerlidir. free()'de region yeniden tag'lenir (ve pointer'ın tag'i artık bayattır), dolayısıyla sonraki bir use-after-free bir mismatch görür; bir out-of-bounds access, allocation'da farklı tag'lenmiş komşu bir granule'e ulaşır. Her iki durumda da mismatch erişim anında raporlanır — redzone veya quarantine olmadan.

Detection olasılıksaldır: rastgele bir collision 1/(2**TS) olasılıkla fark edilmeden geçer — 4-bit tag'lerle yaklaşık %6.25, 8-bit tag'lerle %0.39. Shadow overhead'i belleğin 1/TG'sidir (artı alignment), ASan'ın 1:8 shadow'undan çok daha küçük. TG'den küçük allocation'lar için HWASan bir short granule kullanır: gerçek boyut shadow byte'ında saklanır ve tag granule'ün son byte'ına yerleştirilir.

HWASan'ın TBI'ya ihtiyacı vardır, dolayısıyla AArch64'te natively çalışır; x86_64'te tagging'i page aliasing ile emüle eder (yalnızca heap tagging).

Walkthrough

1. Sanitizer ile build et (AArch64 hedefi, compile ve link'te instrument et):

$ clang --target=aarch64-linux-android30 -fsanitize=hwaddress -O1 -g uaf.c -o uaf

2. Çalıştır ve raporu oku. Free edilmiş bir pointer üzerindeki bir mismatch, bir tag-diagnostic iz üretir:

HWASan tag-mismatch report (use-after-free)
==1==ERROR: HWAddressSanitizer: tag-mismatch on address 0x... at pc 0x...
READ of size 4 at 0x... tags: 7a/3c (ptr/mem) in thread T0
    #0 0x... in main uaf.c:4
...
previously allocated here:
    #0 0x... in main uaf.c:2
Memory tags around the buggy address (one tag corresponds to 16 bytes):
  ... 3c 3c 3c [3c] 3c 3c ...

tags: 7a/3c (ptr/mem) işin kalbidir: pointer hâlâ eski allocation'ın tag'ini taşırken granule yeniden tag'lenmiştir, dolayısıyla erişim reddedilir.

Probabilistic, and a tool not a turnkey defense

4-bit tag'lerle başıboş erişimlerin ~16'da 1'i doğru tag'e alias olup sızabilir; daha yüksek güvence için 8-bit tag'lere genişlet veya deterministik check'lerle eşleştir. HWASan öncelikle bir testing/fuzzing aracıdır (ASan'dan düşük overhead onu daha fazla workload'da uygulanabilir kılar), aynı fikrin production versiyonu ise hardware ARM MTE'dir.

Detection

HWASan'ın kendisi detector'dır: bir tag mismatch'inde pointer vs. memory tag'lerini, erişim boyutunu ve allocation/free stack'lerini yazar; shadow tag-map ise erişimin bir over/under-flow granule'üne mi yoksa free edilmiş bir region'a mı çarptığını konumlandırır.

Mitigation

Testing yerine deployment için ARM MTE ile hardware tagging'e geç; tag'siz platformlar için AddressSanitizer deterministik (ama daha ağır) kapsam verir.

References