AdresDezenfektan

AddressSanitizer (ASan), yerel koddaki bellek hatalarını algılamak için derleyici tabanlı hızlı bir araçtır.

ASan şunları 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

ASan, hem 32-bit hem de 64-bit ARM'de, ayrıca x86 ve x86-64'te çalışır. ASan'ın CPU ek yükü kabaca 2x, kod boyutu ek yükü %50 ile 2x arasında ve büyük bir bellek ek yükü (tahsis modellerinize bağlı olarak, ancak 2x düzeyinde).

Robot 10 ve AArch64 destek üzerinde AOSP ana dal donanım ile hızlandırılmış Aşan (Hwasan) , düşük RAM yük ile benzer bir araç ve saptanan hatalar daha büyük bir aralık. HWASan, ASan tarafından tespit edilen hatalara ek olarak, dönüşten sonra yığın kullanımını algılar.

HWASan benzer CPU ve kod boyutu ek yüküne sahiptir, ancak çok daha küçük bir RAM ek yükü (%15). HWASan deterministik değildir. Yalnızca 256 olası etiket değeri vardır, bu nedenle herhangi bir hatayı kaçırmanın sabit %0,4 olasılığı vardır. HWASan, taşmaları algılamak için ASan'ın sınırlı boyutlu kırmızı bölgelerine ve boş kullanım sonrası kullanımı algılamak için sınırlı kapasiteli karantinaya sahip değildir, bu nedenle HWASan için taşmanın ne kadar büyük olduğu veya belleğin ne kadar süre önce serbest bırakıldığı önemli değildir. Bu, HWASan'ı ASan'dan daha iyi yapar. Sen hakkında daha fazla bilgi edinebilirsiniz Hwasan tasarımı veya kullanımı hakkında Android'de Hwasan .

ASan, yığın/genel yığın taşmalarının yanı sıra yığın taşmalarını da algılar ve minimum bellek yüküyle hızlıdır.

Bu belge, Android'in bölümlerinin/tümünün ASan ile nasıl oluşturulacağını ve çalıştırılacağını açıklar. Eğer Asan ile bir SDK / NDK uygulama oluşturmaya ediyorsanız, bkz Adres Temizleyici yerine.

ASan ile tek tek yürütülebilir dosyaları temizleme

Ekle LOCAL_SANITIZE:=address veya sanitize: { address: true } çalıştırılabilir için yapı kuralı. Mevcut örnekler için kodu arayabilir veya mevcut diğer dezenfektanları bulabilirsiniz.

Bir hata tespit edildiğinde, Asan bir ayrıntılı standart çıkışa ve hem rapor yazdırır logcat ve sonra işlemi çöküyor.

ASan ile paylaşılan kütüphaneleri sterilize etme

ASan'ın çalışma şekli nedeniyle, ASan ile oluşturulmuş bir kitaplık yalnızca ASan ile oluşturulmuş bir yürütülebilir dosya tarafından kullanılabilir.

Tamamı ASan ile oluşturulmayan birden çok yürütülebilir dosyada kullanılan paylaşılan bir kitaplığı sterilize etmek için kitaplığın iki kopyasına ihtiyacınız vardır. Bunu yapmak için önerilen yol için aşağıdaki eklemektir Android.mk söz konusu modül için:

LOCAL_SANITIZE:=address
LOCAL_MODULE_RELATIVE_PATH := asan

Bu koyar kütüphane /system/lib/asan yerine /system/lib . Ardından, yürütülebilir dosyanızı şununla çalıştırın:

LD_LIBRARY_PATH=/system/lib/asan

Sistem deamon`lar için uygun bölüme aşağıdaki eklemek /init.rc veya /init.$device$.rc .

setenv LD_LIBRARY_PATH /system/lib/asan

Süreç dan kütüphaneleri kullandığını doğrulayın /system/lib/asan okuma yoluyla mevcut olduğunda /proc/$PID/maps . Değilse, SELinux'u devre dışı bırakmanız gerekebilir:

adb root
adb shell setenforce 0
# restart the process with adb shell kill $PID
# if it is a system service, or may be adb shell stop; adb shell start.

Daha iyi yığın izleri

ASan, 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'in çoğu çerçeve işaretçileri olmadan oluşturulmuştur. Sonuç olarak, genellikle yalnızca bir veya iki anlamlı kare elde edersiniz. Bunu düzeltmek için kitaplığı ASan ile yeniden oluşturun (önerilir!) veya şununla:

LOCAL_CFLAGS:=-fno-omit-frame-pointer
LOCAL_ARM_MODE:=arm

Veya set ASAN_OPTIONS=fast_unwind_on_malloc=0 süreç ortamında. İkincisi, yüke bağlı olarak çok CPU yoğun olabilir.

sembolizasyon

Başlangıçta, ASan raporları ikili dosyalardaki ve paylaşılan kitaplıklardaki ofsetlere referanslar içerir. Kaynak dosya ve satır bilgilerini almanın iki yolu vardır:

  • Emin olun llvm-symbolizer ikili mevcuttur /system/bin . llvm-symbolizer kaynaklardan inşa edilmiştir third_party/llvm/tools/llvm-symbolizer .
  • Oranı raporu Filtre external/compiler-rt/lib/asan/scripts/symbolize.py senaryo.

İkinci yaklaşım daha fazla veri sağlayabilir (olduğunu file:line konum) çünkü ana bilgisayarda sembolize kütüphanelerin kullanılabilirlik.

Asan uygulamalarda

ASan Java kodunu göremez, ancak JNI kitaplıklarındaki hataları algılayabilir. Bunun için, bu durumda olan Asan ile yürütülebilir inşa etmek gerekir /system/bin/app_process( 32|64 ) . Bu, cihazdaki tüm uygulamalarda aynı anda Asan'ı etkinleştirir, bu da ağır bir yüktür, ancak 2 GB RAM'e sahip bir cihaz bunu kaldırabilmelidir.

Ekle LOCAL_SANITIZE:=address için app_process içinde yapı kuralı frameworks/base/cmds/app_process . Ignore app_process__asan (Eğer bunu okuyun anda hala orada ise) şimdilik aynı dosyada hedef.

Düzenleme service zygote uygun kesit system/core/rootdir/init.zygote( 32|64 ).rc içeren girintili çizgilerin blok için aşağıdaki satırları ekleyin dosya class main , aynı miktarda girintili:

    setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib
    setenv ASAN_OPTIONS allow_user_segv_handler=true

Derleme, adb senkronizasyonu, fastboot flash önyükleme ve yeniden başlatma.

sarma özelliğini kullanma

Önceki bölümdeki yaklaşım, sistemdeki her uygulamaya (aslında, Zygote sürecinin her soyundan gelene) ASan yerleştirir. ASan ile yalnızca bir (veya birkaç) uygulamayı çalıştırmak, daha yavaş uygulama başlatma için bir miktar bellek ek yükü ticareti yapmak mümkündür.

Bu uygulamanızı başlatarak yapılabilir wrap. Emlak. Aşağıdaki örnek, Gmail uygulamasını ASan altında çalıştırır:

adb root
adb shell setenforce 0  # disable SELinux
adb shell setprop wrap.com.google.android.gm "asanwrapper"

Bu bağlamda, asanwrapper yeniden yazar /system/bin/app_process için /system/bin/asan/app_process , Asan ile inşa edildiği. Ayrıca ekler /system/lib/asan dinamik kütüphane arama yolunun başında. Bu şekilde kütüphaneleri Aşan-aletli /system/lib/asan normal kütüphaneler tercih edilir /system/lib ile çalışırken asanwrapper .

Bir hata bulunursa uygulama çöker ve rapor günlüğe yazdırılır.

SANITIZE_TARGET

Android 7.0 ve üstü, tüm Android platformunu ASan ile bir kerede oluşturma desteği içerir. (Android 9'dan daha yüksek bir sürüm oluşturuyorsanız, HWASan daha iyi bir seçimdir.)

Aynı yapı ağacında aşağıdaki komutları çalıştırın.

make -j42
SANITIZE_TARGET=address make -j42

Bu modda, userdata.img ekstra kütüphaneleri içerir ve aynı zamanda cihaza parladı gerekmektedir. Aşağıdaki komut satırını kullanın:

fastboot flash userdata && fastboot flashall

Bu paylaşılan kütüphanelerin iki set oluşturur: normal /system/lib (ilk marka çağırma) ve içinde Asan-instrumented /data/asan/lib (ikinci marka çağırma). İkinci yapıdaki yürütülebilir dosyalar, ilk yapıdakilerin üzerine yazar. Asan-aletli yürütülebilir içeren farklı bir kütüphane arama yolunu almak /data/asan/lib önce /system/lib kullanımı yoluyla /system/bin/linker_asan içinde PT_INTERP .

Yapı sistemi clobbers ara nesne dizinleri zaman $SANITIZE_TARGET değeri değişti. Altında yüklü ikilileri korurken Bu kuvvetler tüm hedeflerin yeniden /system/lib .

Bazı hedefler ASan ile oluşturulamaz:

  • Statik olarak bağlı yürütülebilir dosyalar
  • LOCAL_CLANG:=false hedefleri
  • LOCAL_SANITIZE:=false için ASan'd değildir SANITIZE_TARGET=address

Bu gibi Executables atlanır SANITIZE_TARGET yapı ve ilk yapmak çağırma gelen sürüm kalan /system/bin .

Bunun gibi kütüphaneler Asan olmadan inşa edilir. Bağlı oldukları statik kitaplıklardan bazı ASan kodları içerebilirler.

Destekleyici belgeler