AddressSanitizer berbantuan hardware

Lihat Memahami laporan HWASan untuk mendapatkan informasi tentang cara membaca error HWASan.

AddressSanitizer berbantuan hardware (HWASan) adalah alat deteksi error memori yang mirip dengan AddressSanitizer. HWASan menggunakan RAM yang jauh lebih sedikit dibandingkan dengan ASan, yang membuatnya cocok untuk pembersihan seluruh sistem. HWASan hanya tersedia di Android 10 dan yang lebih tinggi, serta hanya di hardware AArch64.

Meskipun terutama berguna untuk kode C/C++, HWASan juga dapat membantu men-debug kode Java yang menyebabkan error di C/C++ yang digunakan untuk mengimplementasikan antarmuka Java. Hal ini berguna karena dapat mendeteksi error memori saat terjadi, yang mengarahkan Anda langsung ke kode yang bertanggung jawab.

Anda dapat mem-flash image HWASan bawaan ke perangkat Pixel yang didukung dari ci.android.com (petunjuk penyiapan mendetail).

Dibandingkan dengan ASan klasik, HWASan memiliki:

  • Overhead CPU yang serupa (~2x)
  • Overhead ukuran kode yang serupa (40 – 50%)
  • Overhead RAM yang jauh lebih kecil (10% – 35%)

HWASan dapat mendeteksi rangkaian bug yang sama seperti ASan:

  • Stack dan luapan/underflow buffer heap
  • Penggunaan heap setelah tersedia
  • Penggunaan stack di luar cakupan
  • Double free/wild free

Selain itu, HWASan dapat mendeteksi penggunaan stack setelah ditampilkan.

HWASan (sama seperti ASan) kompatibel dengan UBSan, keduanya dapat diaktifkan pada target secara bersamaan.

Detail dan batasan penerapan

HWASan didasarkan pada pendekatan pemberian tag memori, dengan nilai tag acak kecil dikaitkan dengan pointer dan dengan rentang alamat memori. Agar akses memori valid, tag pointer dan memori harus cocok. HWASan mengandalkan fitur ARMv8 top byte ignore (TBI), yang juga disebut pemberian tag alamat virtual, untuk menyimpan tag pointer di bit tertinggi alamat.

Anda dapat membaca lebih lanjut desain HWASan di situs dokumentasi Clang.

Secara desain, HWASan tidak memiliki redzone ukuran terbatas ASan untuk mendeteksi overflow atau karantina kapasitas terbatas ASan untuk mendeteksi penggunaan setelah bebas. Karena alasan ini, HWASan dapat mendeteksi bug terlepas dari seberapa besar overflow atau berapa lama memori dide-alokasikan. Hal ini memberi HWASan keunggulan besar dibandingkan ASan.

Namun, HWASan memiliki jumlah kemungkinan nilai tag yang terbatas (256), yang berarti ada probabilitas 0,4% untuk melewatkan bug selama satu eksekusi program.

Persyaratan

Versi terbaru (4.14+) kernel Android umum mendukung HWASan secara langsung. Cabang khusus Android 10 tidak memiliki dukungan untuk HWASan.

Dukungan ruang pengguna untuk HWASan tersedia mulai dari Android 11.

Jika Anda menggunakan kernel yang berbeda, HWASan mewajibkan kernel Linux untuk menerima pointer berlabel dalam argumen panggilan sistem. Dukungan untuk hal ini diterapkan di patchset upstream berikut:

Jika Anda mem-build dengan toolchain kustom, pastikan toolchain tersebut menyertakan semuanya hingga commit LLVM c336557f.

Menggunakan HWASan

Gunakan perintah berikut untuk membangun seluruh platform menggunakan HWASan:

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

Untuk memudahkan, Anda dapat menambahkan setelan SANITIZE_TARGET ke definisi produk, mirip dengan aosp_coral_hwasan.

Bagi pengguna yang sudah memahami AddressSanitizer, banyak kompleksitas build yang hilang:

  • Tidak perlu menjalankan make dua kali.
  • Build inkremental dapat langsung digunakan.
  • Tidak perlu mem-flash userdata.

Beberapa pembatasan AddressSanitizer juga tidak ada:

  • File yang dapat dieksekusi statis didukung.
  • Anda dapat melewati pembersihan target selain libc. Tidak seperti ASan, tidak ada persyaratan bahwa jika library dibersihkan, semua file yang dapat dieksekusi yang menautkannya juga harus dibersihkan.

Beralih antara image HWASan dan image reguler dengan nomor build yang sama (atau lebih tinggi) dapat dilakukan secara bebas. Anda tidak perlu menghapus total perangkat.

Untuk melewati sanitasi modul, gunakan LOCAL_NOSANITIZE := hwaddress (Android.mk) atau sanitize: { hwaddress: false } (Android.bp).

Membersihkan setiap target

HWASan dapat diaktifkan per target dalam build reguler (tidak bersih), selama libc.so juga dibersihkan. Tambahkan hwaddress: true ke blok pembersihan di "libc_defaults" di bionic/libc/Android.bp. Kemudian, lakukan hal yang sama di target yang sedang Anda kerjakan.

Perhatikan bahwa membersihkan libc memungkinkan pemberian tag pada alokasi memori heap di seluruh sistem, serta pemeriksaan tag untuk operasi memori di dalam libc.so. Tindakan ini dapat menangkap bug bahkan dalam biner tempat HWASan tidak diaktifkan jika akses memori buruk berada di libc.so (misalnya, pthread_mutex_unlock() pada mutex delete()).

Anda tidak perlu mengubah file build apa pun jika seluruh platform dibuat menggunakan HWASan.

Flashstation

Untuk tujuan pengembangan, Anda dapat mem-flash build AOSP yang mengaktifkan HWASan ke perangkat Pixel dengan bootloader yang tidak terkunci menggunakan Flashstation. Pilih target _hwasan, misalnya aosp_flame_hwasan-userdebug. Lihat dokumentasi NDK untuk HWASan bagi developer aplikasi untuk mengetahui detail selengkapnya.

Stack trace yang lebih baik

HWASan menggunakan unwinder berbasis frame pointer yang cepat untuk mencatat pelacakan tumpukan untuk setiap peristiwa alokasi dan dealokasi memori dalam program. Android mengaktifkan pointer frame dalam kode AArch64 secara default, sehingga ini berfungsi dengan baik dalam praktik. Jika Anda perlu memutar kembali melalui kode terkelola, tetapkan HWASAN_OPTIONS=fast_unwind_on_malloc=0 di lingkungan proses. Perhatikan bahwa trace stack akses memori buruk menggunakan unwinder "lambat" secara default; setelan ini hanya memengaruhi trace alokasi dan dealokasi. Opsi ini dapat sangat intensif CPU, bergantung pada beban.

Simbolisasi

Lihat Simbolisasi di "Memahami laporan HWASan".

HWASan dalam aplikasi

Serupa dengan AddressSanitizer, HWASan tidak dapat melihat ke dalam kode Java, tetapi dapat mendeteksi bug dalam library JNI. Hingga Android 14, menjalankan aplikasi HWASan di perangkat non-HWASan tidak didukung.

Di perangkat HWASan, aplikasi dapat diperiksa dengan HWASan dengan mem-build kodenya dengan SANITIZE_TARGET:=hwaddress di Make, atau -fsanitize=hwaddress di flag compiler. Di perangkat non-HWASan (yang menjalankan Android 14 atau yang lebih baru), setelan file wrap.sh LD_HWASAN=1 harus ditambahkan. Lihat dokumentasi developer aplikasi untuk mengetahui detail selengkapnya.