HWASan çökmelerinin nasıl okunacağı hakkında bilgi için HWASan raporlarını anlama bölümüne bakın!
Donanım destekli AddressSanitizer (HWASan), AddressSanitizer'a benzer bir bellek hatası algılama aracıdır. HWASan, ASan'a kıyasla çok daha az RAM kullanır ve bu da onu tüm sistem temizliği için uygun hale getirir. HWASan yalnızca Android 10 ve üzeri sürümlerde ve yalnızca AArch64 donanımında kullanılabilir.
HWASan, öncelikle C/C++ kodu için yararlı olsa da, Java arabirimlerini uygulamak için kullanılan C/C++'da çökmelere neden olan Java kodunda hata ayıklamaya da yardımcı olabilir. Yararlıdır, çünkü meydana geldiklerinde bellek hatalarını yakalar ve sizi doğrudan sorumlu koda yönlendirir.
Önceden oluşturulmuş HWASan görüntülerini ci.android.com'dan desteklenen Pixel cihazlarına flash edebilirsiniz ( ayrıntılı kurulum talimatları ).
Klasik ASan ile karşılaştırıldığında, HWASan'ın özellikleri:
- Benzer CPU yükü (~2x)
- Benzer kod boyutu ek yükü (%40 – %50)
- Çok daha küçük RAM ek yükü (%10 - %35)
HWASan, ASan ile aynı hata grubunu algılar:
- Yığın ve yığın arabellek taşması/yetersizliği
- Serbest kaldıktan sonra yığın kullanımı
- Kapsam dışında yığın kullanımı
- Çift serbest/vahşi ücretsiz
Ek olarak, HWASan dönüşten sonra yığın kullanımını algılar.
HWASan (ASan ile aynı) UBSan ile uyumludur, her ikisi de aynı anda bir hedefte etkinleştirilebilir.
Uygulama ayrıntıları ve sınırlamaları
HWASan, küçük bir rastgele etiket değerinin hem işaretçiler hem de bellek adres aralıkları ile ilişkilendirildiği bellek etiketleme yaklaşımına dayanmaktadır. Bir bellek erişiminin geçerli olması için işaretçi ve bellek etiketlerinin eşleşmesi gerekir. HWASan, işaretçi etiketini adresin en yüksek bitlerinde depolamak için sanal adres etiketleme olarak da adlandırılan ARMv8 özelliği üst bayt yok saymaya (TBI) güvenir.
HWASan'ın tasarımı hakkında daha fazla bilgiyi Clang dokümantasyon sitesinde okuyabilirsiniz.
Tasarım gereği, HWASan, taşmaları algılamak için ASan'ın sınırlı boyutlu kırmızı bölgelerine veya ücretsiz kullanımdan sonra kullanımı algılamak için ASan'ın sınırlı kapasiteli karantinasına sahip değildir. Bu nedenle, HWASan, taşma ne kadar büyük olursa olsun veya belleğin ne kadar süre önce serbest bırakıldığına bakılmaksızın bir hatayı algılayabilir. Bu, HWASan'a Asan'a göre büyük bir avantaj sağlar.
Bununla birlikte, HWASan'ın sınırlı sayıda olası etiket değeri vardır (256), bu da programın bir yürütmesi sırasında herhangi bir hatayı kaçırma olasılığının %0.4 olduğu anlamına gelir.
Gereksinimler
Ortak Android çekirdeğinin son sürümleri (4.14+), kullanıma hazır HWASan'ı destekler. Android 10'a özel dalların HWASan desteği yoktur.
HWASan için kullanıcı alanı desteği, Android 11'den itibaren mevcuttur.
Farklı bir çekirdekle çalışıyorsanız, HWASan, Linux çekirdeğinin sistem çağrısı argümanlarında etiketlenmiş işaretçileri kabul etmesini gerektirir. Bunun için destek, aşağıdaki yukarı akış yama setlerinde uygulandı:
- arm64 etiketli adres ABI
- arm64: çekirdeğe iletilen kullanıcı işaretçilerinin etiketini kaldırın
- mm: brk()/mmap()/mremap() içinde sanal adres takma adları oluşturmaktan kaçının
- arm64: kernel iş parçacıklarından çağrılan access_ok() içindeki etiketli adresleri doğrulayın
Özel bir araç zinciriyle oluşturuyorsanız, LLVM commit c336557f'ye kadar her şeyi içerdiğinden emin olun.
HWASan'ı kullanma
HWASan kullanarak tüm platformu oluşturmak için aşağıdaki komutları kullanın:
lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j
Kolaylık sağlamak için, aosp_coral_hwasan'a benzer bir ürün tanımına SANITIZE_TARGET ayarını ekleyebilirsiniz.
AddressSanitizer'a aşina olan kullanıcılar için, birçok yapı karmaşıklığı ortadan kalktı:
- İki kez make çalıştırmaya gerek yok.
- Artımlı yapılar kutunun dışında çalışır.
- Kullanıcı verilerini flaş etmeye gerek yok.
Bazı AddressSanitizer kısıtlamaları da kaldırıldı:
- Statik yürütülebilir dosyalar desteklenir.
- libc dışındaki herhangi bir hedefin sanitizasyonunu atlamak sorun değil. ASan'dan farklı olarak, bir kitaplık sterilize edilmişse, onu bağlayan herhangi bir yürütülebilir dosyanın da olması gerektiği gibi bir gereklilik yoktur.
Aynı (veya daha yüksek) yapı numarasına sahip HWASan ve normal görüntüler arasında geçiş serbestçe yapılabilir. Cihazın silinmesi gerekli değildir.
Bir modülün sterilize edilmesini atlamak için LOCAL_NOSANITIZE := hwaddress
(Android.mk) veya sanitize: { hwaddress: false }
(Android.bp) kullanın.
Bireysel hedefleri dezenfekte etme
HWASan, libc.so
da sterilize edildiği sürece, normal (temizlenmemiş) bir yapıda hedef başına etkinleştirilebilir. bionic/libc/Android.bp içindeki "libc_defaults"
içindeki sanitize bloğuna hwaddress: true
ekleyin. Ardından, üzerinde çalıştığınız hedefte de aynısını yapın.
Libc'yi temizlemenin, sistem genelinde yığın bellek ayırmalarının etiketlenmesinin yanı sıra libc.so
içindeki bellek işlemleri için etiketlerin kontrol edilmesini sağladığını unutmayın. Bu, hatalı bellek erişimi libc.so
(örneğin, bir delete()
ed mutex üzerinde pthread_mutex_unlock()
HWASan'ın etkinleştirilmediği ikili dosyalarda bile hataları yakalayabilir.
Tüm platform HWASan kullanılarak oluşturulmuşsa, herhangi bir derleme dosyasının değiştirilmesi gerekli değildir.
flaş istasyonu
Geliştirme amacıyla, Flashstation kullanarak kilidi açılmış önyükleyicili bir Pixel cihazına HWASan etkinleştirilmiş bir AOSP yapısı yükleyebilirsiniz . _hwasan hedefini seçin, örneğin aosp_flame_hwasan-userdebug. Daha fazla ayrıntı için uygulama geliştiricileri için HWASan NDK belgelerine bakın.
Daha iyi yığın izleri
HWASan, programdaki her bellek ayırma ve ayırma olayı için bir yığın izlemesi kaydetmek için hızlı, çerçeve işaretçisi tabanlı bir çözücü kullanır. Android, varsayılan olarak AArch64 kodunda çerçeve işaretçilerini etkinleştirir, bu nedenle pratikte bu harika çalışır. Yönetilen kod aracılığıyla gevşemeniz gerekiyorsa, işlem ortamında HWASAN_OPTIONS=fast_unwind_on_malloc=0
olarak ayarlayın. Kötü bellek erişimi yığın izlerinin varsayılan olarak "yavaş" sarıcıyı kullandığını unutmayın; bu ayar yalnızca ayırma ve ayırma izlerini etkiler. Bu seçenek, yüke bağlı olarak çok CPU yoğun olabilir.
sembolizasyon
" HWASan raporlarını anlama" bölümündeki Sembolleştirmeye bakın.
Uygulamalarda HWASan
AddressSanitizer'a benzer şekilde, HWASan Java kodunu göremez, ancak JNI kitaplıklarındaki hataları algılayabilir. ASan'dan farklı olarak, HWASan uygulamalarının HWASan olmayan bir cihazda çalıştırılması desteklenmez.
Bir HWASan cihazında uygulamalar, Make'da SANITIZE_TARGET:=hwaddress
veya derleyici bayraklarında -fsanitize=hwaddress
ile kodlarını oluşturarak HWASan ile kontrol edilebilir. Daha fazla ayrıntı için uygulama geliştirici belgelerine bakın.