Scudo

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 işlemi için temel işlevler (ör. malloc ve free) ve C++ temel işlevleri (ör. new ve delete) 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 itibaren, tüm yerel kodlar için scudo kullanılır (jemalloc'un hâlâ kullanıldığı düşük bellek kapasiteli 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. Scudo çalışma zamanı, Android araç zincirinin bir parçası olarak gönderilir ve ayırıcının ikili dosyada kolayca etkinleştirilmesine olanak tanımak için Soong ve Make'e destek eklenmiştir.

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 Varsayılan olarak 64 bit Varsayılan olarak 32 bit 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ı azaltabilir ancak azaltma işleminin etkinliğini düşürebilir. Negatif bir değer, varsayılan değerlere geri döner. Hem bu değeri hem de ThreadLocalQuarantineSizeKb değerini sıfıra ayarlamak, karantinayı tamamen devre dışı bırakır.
QuarantineChunksUpToSize 2048 512 Parçaların karantinaya alınabileceği maksimum boyut (bayt cinsinden).
ThreadLocalQuarantineSizeKb 64 16 Dünya geneli karantinadan yük kaldırmak için kullanılan iş parçacığı başına önbellek kullanımının 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 bırakmaya çalışır ancak bu aralıktan (milisaniye cinsinden) daha sık olmaz. Değer negatifse bellek işletim sistemine 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 CTS testi yoktur. Bunun yerine, cihazı etkilemediğini doğrulamak için belirli bir ikili programda Scudo'nun etkinleştirilip etkinleştirilmediğine bakılmaksızın CTS testlerinin geçtiğinden emin olun.

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 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ılmıyor veya parçayı geri dönüştürmeye çalışırken karantinaya alınmıyordur. 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çi uyumsuzdur.
  • allocation type mismatch: Bu seçenek etkinleştirildiğinde, bir parça üzerinde ç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 derleyici sorunudur veya ayrılan nesneyle ilgili bir tür karışıklığıdır.
  • 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. Bir uygulamadaki kilitlenmeyle ilgili hata ayıklama yapıyorsanız HWASan uygulama derlemesi de kullanabilirsiniz.