Scudo

Scudo, performansını 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ısı veya yığın ayırıcısıdır. Standart C ayırma ve serbest bırakma temel öğelerini (ör. malloc ve free) ve C++ temel öğelerini (ör. new ve delete) sağlar.

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

Android 11'in yayınlanmasından bu yana, tüm yerel kodlar için scudo kullanılır (düşük bellekli cihazlar hariç. Bu cihazlarda jemalloc kullanılmaya devam eder). Çalışma zamanında, tüm yerel yığın ayırma ve serbest bırakma işlemleri, tüm yürütülebilir dosyalar ve bunların kitaplık bağımlılıkları için Scudo tarafından gerçekleştirilir. Yığında bozulma veya şüpheli davranış tespit edilirse işlem durdurulur.

Scudo, açık kaynaklıdır ve LLVM'nin compiler-rt projesinin bir parçasıdır. Belgeleri https://llvm.org/docs/ScudoHardenedAllocator.html adresinde bulabilirsiniz. Scudo çalışma zamanı, Android araç zincirinin bir parçası olarak gönderilir ve Soong ile Make'e, ikili dosyada ayırıcının kolayca etkinleştirilmesine olanak tanıyan destek eklenmiştir.

Aşağıda açıklanan seçenekleri kullanarak, tahsis edicide ek azaltma özelliğini etkinleştirebilir veya devre dışı bırakabilirsiniz.

Özelleştirme

Ayırıcının bazı parametreleri, birkaç yöntemle işlem bazında tanımlanabilir:

  • Statik olarak: Ayrıştırılacak seçenekler dizesini döndüren bir __scudo_default_options işlevi tanımlayın. Bu işlevin şu prototipi 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.

Seçenek Varsayılan olarak 64 bit 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ı azaltabilir ancak azaltma işleminin etkinliğini düşürebilir. Negatif bir değer, varsayılan değerlere geri döner. Hem bu ayarın hem de ThreadLocalQuarantineSizeKb ayarının 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 karantinayı yük aktarmak için 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 ayarın hem de QuarantineSizeKb ayarının sıfıra ayarlanması, karantina özelliğini tamamen devre dışı bırakır.
DeallocationTypeMismatch false false malloc/delete, new/free, new/delete[] üzerinde hata raporlamayı etkinleştirir.
DeleteSizeMismatch true true Yeni ve silinen boyutlar arasındaki uyuşmazlıkta hata raporlamasını etkinleştirir.
ZeroContents false false Ayırma ve ayırmayı kaldırma işlemlerinde sıfır yığın içeriklerini etkinleştirir.
allocator_may_return_null false false Ayırıcının, işlemi sonlandırmak yerine kurtarılabilir bir hata oluştuğunda 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, RSS yeni tahsislere izin verecek şekilde tekrar düşene kadar ek tahsisler başarısız olur veya null (allocator_may_return_null değerine bağlı olarak) döndürülür.
allocator_release_to_os_interval_ms 5000 Yok Yalnızca 64 bit 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 yapmaz. Değer negatifse 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 tasarlanmış CTS testleri bulunmamaktadır. Bunun yerine, cihazı etkilemediğini doğrulamak için CTS testlerinin, belirli bir ikili program için Scudo etkinleştirilmiş veya devre dışı bırakılmış halde geçtiğinden emin olun.

Sorun giderme

Kurtarılamayan bir sorun algılanırsa ayırıcı, standart hata tanımlayıcısına bir hata mesajı gösterir ve ardından işlemi sonlandırır. Sonlandırmaya yol açan yığın izlemeleri, sistem günlüğüne eklenir. Çıkış genellikle Scudo ERROR: ile başlar ve ardından sorunla ilgili kısa bir özet ve ipuçları yer alır.

Mevcut hata mesajlarının ve olası nedenlerinin listesini aşağıda bulabilirsiniz:

  • 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 (kısmen veya tamamen) üzerine yazılmıştır ya da işleve iletilen işaretçi bir parça değildir.
  • race on chunk header: İki farklı iş parçacığı aynı anda aynı başlığı değiştirmeye çalışıyor. Bu durum genellikle söz konusu parçada işlemler gerçekleştirilirken yarışma koşulundan veya genel bir kilitleme eksikliğinden kaynaklanır.
  • invalid chunk state: Parça, belirli bir işlem için beklenen durumda değil. Örneğin, serbest bırakılmaya çalışıldığında ayrılmamış veya geri dönüştürülmeye çalışıldığında karantinaya alınmamış. Bu hatanın tipik nedeni çift boşaltmadır.
  • misaligned pointer: Temel hizalama gereksinimleri sıkı bir şekilde 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 hizalanmamış demektir.
  • allocation type mismatch: Bu seçenek etkinleştirildiğinde, bir parçada çağrılan serbest bırakma işlevinin, onu 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 parçanın serbest bırakılması sırasında iletilen boyut ile ayrılması sırasında istenen boyut arasında uyuşmazlık oluşur. Bu durum genellikle derleyiciyle ilgili bir sorundan veya serbest bırakılan nesnede tür karışıklığından kaynaklanır.
  • RSS limit exhausted: İsteğe bağlı olarak belirtilen maksimum RSS değeri aşıldı.

İşletim sisteminin kendisindeki bir kilitlenmede hata ayıklıyorsanız HWASan OS derlemesi kullanabilirsiniz. Bir uygulamadaki kilitlenme sorununu ayıklıyorsanız HWASan uygulama derlemesi de kullanabilirsiniz.