Scudo Dili

Scudo, performansı korurken yığınla ilgili güvenlik açıklarına (ör. yığın tabanlı arabellek taşması, boşaltıldıktan sonra kullanım ve çift boşaltma) karşı dayanıklı olacak şekilde tasarlanmış dinamik bir kullanıcı modu bellek ayırıcı veya yığın ayırıcıdır. Standart C ayırma ve ayırma temel öğelerinin (ör. malloc ve ücretsiz) yanı sıra C++ temel öğelerini (yeni ve sil gibi) sağlar.

Scudo, AddressSanitizer (ASan) gibi tam teşekküllü bir bellek hatası algılayıcısından ziyade bir azaltma aracıdır.

Android 11 sürümünden bu yana scudo tüm yerel kodlar için kullanılır (jemalloc'un hâlâ kullanıldığı düşük bellekli cihazlar hariç). Tüm yürütülebilir dosyalar ve kitaplık bağımlılıkları için çalışma zamanında tüm yerel yığın tahsisleri ve tahsis iptalleri Scudo tarafından sağlanır. Yığınta bozulma veya şüpheli davranış tespit edilirse işlem iptal edilir.

Scudo, açık kaynaklı bir yazılımdır ve LLVM'in compiler-rt projesinin bir parçasıdır. Belgelere https://llvm.org/docs/ScudoHardenedAllocator.html adresinden ulaşabilirsiniz. Android araç zincirinin bir parçası olarak Scudo çalışma zamanı gönderilirken, ayırıcının bir ikili programda kolayca etkinleştirilmesi için Soong and Make bölümüne destek eklendi.

Aşağıda açıklanan seçenekleri kullanarak dağıtıcıda ek azaltmayı etkinleştirebilir veya devre dışı bırakabilirsiniz.

Özelleştirme

Ayıracın bazı parametreleri, aşağıdaki yöntemlerden biri kullanılarak işlem bazında tanımlanabilir:

  • Statik olarak: Programda, ayrıştırılacak seçenekler dizesini döndüren bir __scudo_default_options işlevi tanımlayın. Bu işlevin prototipi şu şekilde olmalıdır: extern "C" const char *__scudo_default_options().
  • Dinamik olarak: Ayrıştırılacak seçenekler dizesini içeren SCUDO_OPTIONS ortam değişkenini kullanın. Bu şekilde tanımlanan seçenekler, __scudo_default_options aracılığıyla yapılan tüm tanımları geçersiz kılar.

Aşağıdaki seçenekler kullanılabilir.

Option 64 bit varsayılan 32 bit varsayılan Açıklama
QuarantineSizeKb 256 64 Parçaların gerçek tahsisini geciktirmek için kullanılan karantinanın boyutu (KB cinsinden). Daha düşük bir değer bellek kullanımını azaltır ancak çözümün etkisini azaltabilir. Negatif bir değer varsayılan değerlere döner. Hem bunun hem de ThreadLocalQuarantineSizeKb değerinin sıfıra ayarlanması karantinayı tamamen devre dışı bırakır.
QuarantineChunksUpToSize 2048 512 Parçaların karantinaya alınabileceği maksimum boyut (bayt cinsinden).
ThreadLocalQuarantineSizeKb 64 16 Genel karantinadan yük almak için kullanılan iş parçacığı başına önbellek boyutu (KB cinsinden). Daha düşük bir değer, bellek kullanımını azaltabilir ancak genel karantinadaki çekişmeyi artırabilir. Hem bu değeri hem de QuarantineSizeKb değerini sıfıra ayarlamak, karantinayı tamamen devre dışı bırakır.
DeallocationTypeMismatch false false Malloc/delete, new/free, new/delete[] için hata raporlamayı etkinleştirir
DeleteSizeMismatch true true Yeni ve silinen öğelerin boyutları arasında uyuşmazlık olduğunda hata raporlamasını etkinleştirir.
ZeroContents false false Ayırma ve ayırma işleminde sıfır parça içeriğini etkinleştirir.
allocator_may_return_null false false Kurtarılabilecek bir hata oluştuğunda, ayırıcının işlemi sonlandırmak yerine null döndürebileceğini belirtir.
hard_rss_limit_mb 0 0 İşlemin RSS'si bu sınıra ulaştığında işlem sonlandırılır.
soft_rss_limit_mb 0 0 İşlemin RSS'si bu sınıra ulaştığında, yeni atamalara izin vermek için RSS tekrar aşağı inene kadar daha fazla atama başarısız olur veya null değerini döndürür (allocator_may_return_null değerine bağlı olarak).
allocator_release_to_os_interval_ms Yok 5000 Yalnızca 64 bitlik bir ayırıcıyı etkiler. Ayarlanırsa kullanılmayan belleği işletim sistemine serbest bırakmaya çalışır ancak bu aralıktan (milisaniye cinsinden) daha sık olmayacak şekilde. Değer negatif olursa bellek, işletim sistemine serbest bırakılmaz.
abort_on_error true true Ayarlanırsa araç, hata mesajını yazdırdıktan sonra _exit() yerine abort() işlevini çağırır.

Doğrulama

Şu anda Scudo için özel olarak CTS testi yoktur. Bunun yerine, belirli bir ikili program için CTS testlerinin Scudo etkin olsa da olmasa da başarılı olduğundan emin olarak testin cihazı etkilemediğini doğrulayın.

Sorun giderme

Kurtarılamayacak bir sorun tespit edilirse ayırıcı, standart hata tanımlayıcısı için bir hata mesajı gösterir ve ardından işlemi sonlandırır. Sonlandırmaya neden olan yığın izlemeleri sistem günlüğüne eklenir. Çıkış genellikle Scudo ERROR: ile başlar ve ardından ipuçlarıyla birlikte sorunun kısa bir özeti gelir.

Mevcut hata mesajlarının ve olası nedenlerinin listesi aşağıda verilmiştir:

  • corrupted chunk header: Parça başlığının sağlama toplamı doğrulaması başarısız oldu. Bunun nedeni muhtemelen iki şeyden biridir: Başlık üzerine yazılmıştır (kısmen veya tamamen) veya işleve iletilen işaretçi bir parça değildir.
  • race on chunk header: İki farklı ileti dizisi aynı anda aynı başlığı değiştirmeye çalışıyor. Bu durum genellikle bir yarış koşulunun veya söz konusu parça üzerinde işlem yapılırken genel olarak kilitleme eksikliğinin belirtisidir.
  • invalid chunk state: Parça, belirli bir işlem için beklenen durumda değildir. Örneğin, parçayı serbest bırakmaya çalışırken ayrılmamış veya geri dönüştürmeye çalışırken karantinaya alınmamıştır. Bu hatanın yaygın nedeni, çift serbest bırakmadır.
  • misaligned pointer: Temel hizalama koşulları kesinlikle uygulanır: 32 bit platformlarda 8 bayt, 64 bit platformlarda 16 bayt. İşlevlerimize iletilen bir işaretçi bunlara uymuyorsa işlevlerden birine iletilen işaretçinin hizası bozulmuş demektir.
  • allocation type mismatch: Bu seçenek etkinleştirildiğinde, bir parçada çağrılan bir ayırma işlevinin, parçayı ayırmak için çağrılan işlevin türüyle eşleşmesi gerekir. Bu tür bir uyuşmazlık güvenlik sorunlarına yol açabilir.
  • invalid sized delete: C++14 boyutlu silme operatörü kullanıldığında ve isteğe bağlı kontrol etkinleştirildiğinde, bir yığının tahsisi kaldırıldığında iletilen boyut ile yığının tahsisi sırasında istenen boyut arasında uyuşmazlık vardır. Bu genellikle bir derleyici sorunu veya ayrılan nesneyle ilgili bir tür karışıklığı olur.
  • RSS limit exhausted: İsteğe bağlı olarak belirtilen maksimum RSS aşıldı.

OS'deki bir kilitlenmeden hata ayıklıyorsanız HWASan OS derlemesini kullanabilirsiniz. Uygulamadaki bir kilitlenmede hata ayıklıyorsanız HWASan uygulama derlemesi de kullanabilirsiniz.