Scudo

Scudo adalah pengalokasi memori mode pengguna dinamis, atau pengalokasi heap , yang dirancang untuk tahan terhadap kerentanan terkait heap (seperti buffer overflow berbasis heap , use after free , dan double free ) sambil mempertahankan kinerja. Ini menyediakan alokasi C standar dan primitif deallokasi (seperti malloc dan gratis), serta primitif C++ (seperti baru dan hapus).

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

Mulai dari rilis Android 11, scudo digunakan untuk semua kode asli (kecuali pada perangkat dengan memori rendah, di mana jemalloc masih digunakan). Saat runtime, semua alokasi heap asli dan deallocation dilayani oleh Scudo untuk semua executable dan dependensi library mereka, dan proses dibatalkan jika korupsi atau perilaku mencurigakan terdeteksi di heap.

Di Android 10, scudo harus diaktifkan per biner dengan menyetel opsi LOCAL_SANITIZE := scudo di file .mk atau sanitize: { scudo: true, } di file .bp.

Scudo adalah open source dan bagian dari proyek compiler-rt LLVM. Dokumentasi tersedia di https://llvm.org/docs/ScudoHardenedAllocator.html . Runtime Scudo dikirimkan sebagai bagian dari rantai alat Android dan dukungan telah ditambahkan ke Soong dan Make untuk memudahkan pengaktifan pengalokasi dalam biner.

Anda dapat mengaktifkan atau menonaktifkan mitigasi ekstra dalam pengalokasi menggunakan opsi yang dijelaskan di bawah ini.

Kustomisasi

Beberapa parameter pengalokasi dapat ditentukan berdasarkan per-proses melalui beberapa cara:

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

Opsi berikut tersedia.

Pilihan Standar 64-bit Standar 32-bit Keterangan
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 jatuh kembali ke default. Menyetel ini dan ThreadLocalQuarantineSizeKb ke nol akan menonaktifkan karantina sepenuhnya.
QuarantineChunksUpToSize 2048 512 Ukuran (dalam byte) hingga potongan mana yang dapat dikarantina.
ThreadLocalQuarantineSizeKb 64 16 Ukuran (dalam KB) cache per-utas digunakan untuk membongkar karantina global. Nilai yang lebih rendah dapat mengurangi penggunaan memori tetapi dapat meningkatkan pertentangan di karantina global. Menyetel ini dan QuarantineSizeKb ke nol akan menonaktifkan karantina sepenuhnya.
DeallocationTypeMismatch false false Mengaktifkan pelaporan kesalahan pada malloc/delete, new/free, new/delete[]
DeleteSizeMismatch true true Memungkinkan pelaporan kesalahan pada ketidakcocokan antara ukuran baru dan hapus.
ZeroContents false false Mengaktifkan konten potongan nol pada alokasi dan dealokasi.
allocator_may_return_null false false Menentukan bahwa pengalokasi dapat mengembalikan null saat terjadi kesalahan yang dapat dipulihkan, alih-alih menghentikan proses.
hard_rss_limit_mb 0 0 Saat RSS proses mencapai batas ini, proses akan dihentikan.
soft_rss_limit_mb 0 0 Saat proses RSS mencapai batas ini, alokasi selanjutnya gagal atau mengembalikan null (bergantung pada nilai allocator_may_return_null ), hingga RSS kembali turun untuk memungkinkan alokasi baru.
allocator_release_to_os_interval_ms T/A 5000 Hanya mempengaruhi pengalokasi 64-bit. Jika disetel, coba lepaskan memori yang tidak digunakan ke OS, tetapi tidak lebih sering dari interval ini (dalam milidetik). Jika nilainya negatif, memori tidak dilepaskan ke OS.
abort_on_error true true Jika disetel, alat akan memanggil abort() alih-alih _exit() setelah mencetak pesan kesalahan.

Validasi

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

Penyelesaian masalah

Jika masalah yang tidak dapat dipulihkan terdeteksi, pengalokasi menampilkan pesan kesalahan ke deskriptor kesalahan standar dan kemudian menghentikan proses. Jejak tumpukan yang mengarah ke penghentian ditambahkan di log sistem. Output biasanya dimulai dengan Scudo ERROR: diikuti dengan ringkasan singkat dari masalah bersama dengan petunjuk apa pun.

Berikut adalah daftar pesan kesalahan saat ini dan kemungkinan penyebabnya:

  • corrupted chunk header : Verifikasi checksum dari header chunk telah gagal. Ini kemungkinan karena salah satu dari dua hal: header ditimpa (sebagian atau seluruhnya), atau pointer yang diteruskan ke fungsi bukan potongan.
  • race on chunk header : Dua utas berbeda mencoba memanipulasi header yang sama secara bersamaan. Ini biasanya merupakan gejala dari kondisi balapan atau kurangnya penguncian saat melakukan operasi pada potongan itu.
  • invalid chunk state : Potongan tidak dalam keadaan yang diharapkan untuk operasi tertentu, misalnya, tidak dialokasikan saat mencoba membebaskannya, atau tidak dikarantina saat mencoba mendaur ulangnya. Gratis ganda adalah alasan umum untuk kesalahan ini.
  • misaligned pointer : Persyaratan penyelarasan dasar sangat ditegakkan: 8 byte pada platform 32-bit dan 16 byte pada platform 64-bit. Jika penunjuk yang diteruskan ke fungsi kita tidak cocok dengan itu, penunjuk yang diteruskan ke salah satu fungsi tidak sejajar.
  • allocation type mismatch : Ketika opsi ini diaktifkan, fungsi deallokasi yang dipanggil pada potongan harus cocok dengan tipe fungsi yang dipanggil untuk mengalokasikannya. Jenis ketidakcocokan ini dapat menimbulkan masalah keamanan.
  • invalid sized delete : Ketika operator hapus berukuran C++14 digunakan, dan pemeriksaan opsional diaktifkan, ada ketidakcocokan antara ukuran yang diteruskan saat membatalkan alokasi potongan dan ukuran yang diminta saat mengalokasikannya. Ini biasanya masalah kompiler atau kebingungan tipe pada objek yang tidak dialokasikan.
  • RSS limit exhausted : RSS maksimum yang ditentukan secara opsional telah terlampaui.

Jika Anda men-debug kerusakan di OS itu sendiri, Anda dapat menggunakan build OS HWASan . Jika Anda men-debug kerusakan di aplikasi, Anda juga dapat menggunakan build aplikasi HWASan .