Scudo

Scudo adalah alokator memori mode pengguna dinamis, atau alokator heap, yang dirancang agar tahan terhadap kerentanan terkait heap (seperti buffer berbasis heap overflow, penggunaan setelah dibebaskan, dan pembebasan ganda) sekaligus mempertahankan performa. Alokator ini menyediakan primitif alokasi dan dealokasi C standar (seperti malloc dan free), serta primitif C++ (seperti new dan delete).

Scudo lebih merupakan mitigasi daripada detektor error memori yang lengkap seperti AddressSanitizer (ASan).

Sejak rilis Android 11, scudo digunakan untuk semua kode native (kecuali pada perangkat dengan memori rendah, tempat jemalloc masih digunakan). Saat runtime, semua alokasi dan dealokasi heap native dilayani oleh Scudo untuk semua file yang dapat dieksekusi dan dependensi library-nya, dan proses akan dihentikan jika perilaku yang mencurigakan atau kerusakan terdeteksi di heap.

Scudo adalah open source dan merupakan bagian dari project compiler-rt LLVM. Dokumentasi tersedia di https://llvm.org/docs/ScudoHardenedAllocator.html. Runtime Scudo dikirimkan sebagai bagian dari toolchain Android dan dukungan ditambahkan ke Soong dan Make untuk memungkinkan pengaktifan alokator yang mudah dalam biner.

Anda dapat mengaktifkan atau menonaktifkan mitigasi tambahan dalam alokator menggunakan opsi yang dijelaskan di bawah.

Penyesuaian

Beberapa parameter alokator dapat ditentukan per proses melalui beberapa cara:

  • Secara statis: Tentukan fungsi __scudo_default_options dalam program yang menampilkan string opsi yang akan diuraikan. Fungsi ini harus memiliki prototipe berikut: extern "C" const char *__scudo_default_options().
  • Secara dinamis: Gunakan variabel lingkungan SCUDO_OPTIONS yang berisi string opsi yang akan diuraikan. Opsi yang ditentukan dengan cara ini akan mengganti definisi apa pun yang dibuat melalui __scudo_default_options.

Opsi berikut tersedia.

Opsi Default 64-bit Default 32-bit Deskripsi
QuarantineSizeKb 256 64 Ukuran (dalam KB) karantina yang digunakan untuk menunda dealokasi sebenarnya dari potongan. Nilai yang lebih rendah dapat mengurangi penggunaan memori, tetapi mengurangi efektivitas mitigasi; nilai negatif akan kembali ke nilai default. Menetapkan nilai ini dan ThreadLocalQuarantineSizeKb ke nol akan menonaktifkan karantina sepenuhnya.
QuarantineChunksUpToSize 2048 512 Ukuran (dalam byte) hingga potongan dapat dikarantina.
ThreadLocalQuarantineSizeKb 64 16 Ukuran (dalam KB) penggunaan cache per thread untuk mengurangi beban karantina global. Nilai yang lebih rendah dapat mengurangi penggunaan memori, tetapi dapat meningkatkan pertentangan pada karantina global. Menetapkan nilai ini dan QuarantineSizeKb ke nol akan menonaktifkan karantina sepenuhnya.
DeallocationTypeMismatch false false Mengaktifkan pelaporan error pada malloc/delete, new/free, new/delete[]
DeleteSizeMismatch true true Mengaktifkan pelaporan error pada ketidakcocokan antara ukuran new dan delete.
ZeroContents false false Mengaktifkan konten potongan nol pada alokasi dan dealokasi.
allocator_may_return_null false false Menentukan bahwa alokator dapat menampilkan null saat terjadi error yang dapat dipulihkan, bukan menghentikan proses.
hard_rss_limit_mb 0 0 Saat RSS proses mencapai batas ini, proses akan dihentikan.
soft_rss_limit_mb 0 0 Saat RSS proses mencapai batas ini, alokasi lebih lanjut akan gagal atau menampilkan null (bergantung pada nilai allocator_may_return_null), hingga RSS kembali turun untuk memungkinkan alokasi baru.
allocator_release_to_os_interval_ms 5000 T/A Hanya memengaruhi alokator 64-bit. Jika ditetapkan, mencoba melepaskan memori yang tidak digunakan ke OS, tetapi tidak lebih sering dari interval ini (dalam milidetik). Jika nilainya negatif, memori tidak akan dilepaskan ke OS.
abort_on_error true true Jika ditetapkan, alat akan memanggil abort() dan bukan _exit() setelah mencetak pesan error.

Validasi

Saat ini, tidak ada pengujian CTS khusus untuk Scudo. Sebagai gantinya, pastikan pengujian CTS lulus dengan atau tanpa Scudo diaktifkan untuk program biner tertentu guna memverifikasi bahwa pengujian tersebut tidak memengaruhi perangkat.

Pemecahan masalah

Jika masalah yang tidak dapat dipulihkan terdeteksi, alokator akan menampilkan pesan error ke deskriptor error standar, lalu menghentikan proses. Pelacakan tumpukan yang menyebabkan penghentian ditambahkan dalam log sistem. Output biasanya dimulai dengan Scudo ERROR: diikuti dengan ringkasan singkat masalah beserta pointer apa pun.

Berikut adalah daftar pesan error saat ini dan kemungkinan penyebabnya:

  • corrupted chunk header: Verifikasi checksum header potongan gagal. Hal ini kemungkinan disebabkan oleh salah satu dari dua hal: header ditimpa (sebagian atau seluruhnya), atau pointer yang diteruskan ke fungsi bukan potongan.
  • race on chunk header: Dua thread berbeda mencoba memanipulasi header yang sama pada waktu yang sama. Hal ini biasanya merupakan gejala kondisi race atau kurangnya penguncian umum saat melakukan operasi pada potongan tersebut.
  • invalid chunk state: Potongan tidak dalam status yang diharapkan untuk operasi tertentu, misalnya, tidak dialokasikan saat mencoba membebaskannya, atau tidak dikarantina saat mencoba mendaur ulangnya. Pembebasan ganda adalah alasan umum untuk error ini.
  • misaligned pointer: Persyaratan perataan dasar sangat diterapkan: 8 byte pada platform 32-bit dan 16 byte pada platform 64-bit. Jika pointer yang diteruskan ke fungsi kami tidak sesuai dengan persyaratan tersebut, pointer yang diteruskan ke salah satu fungsi tidak selaras.
  • allocation type mismatch: Jika opsi ini diaktifkan, fungsi dealokasi yang dipanggil pada potongan harus cocok dengan jenis fungsi yang dipanggil untuk mengalokasikannya. Jenis ketidakcocokan ini dapat menimbulkan masalah keamanan.
  • invalid sized delete: Saat operator delete berukuran C++14 digunakan, dan pemeriksaan opsional diaktifkan, ada ketidakcocokan antara ukuran yang diteruskan saat mendealokasikan potongan dan ukuran yang diminta saat mengalokasikannya. Hal ini biasanya merupakan masalah compiler atau kebingungan jenis pada objek yang sedang didealokasikan.
  • RSS limit exhausted: RSS maksimum yang ditentukan secara opsional telah terlampaui.

Jika melakukan proses debug error di OS itu sendiri, Anda dapat menggunakan build OS HWASan. Jika melakukan proses debug error di aplikasi, Anda juga dapat menggunakan build aplikasi HWASan juga.