Lihat Memahami laporan HWASan untuk mengetahui informasi tentang cara membaca error HWASan.
Hardware-assisted AddressSanitizer (HWASan) adalah alat deteksi error memori yang mirip dengan AddressSanitizer. HWASan menggunakan RAM yang jauh lebih sedikit dibandingkan dengan ASan, sehingga cocok untuk sanitasi seluruh sistem. HWASan hanya tersedia di Android 10 dan yang lebih tinggi, dan 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 menangkap error memori saat terjadi, sehingga langsung menunjukkan kode yang bertanggung jawab.
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 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, di mana nilai tag acak kecil dikaitkan dengan pointer dan rentang alamat memori. Agar akses memori valid, tag penunjuk 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 selengkapnya tentang desain HWASan di situs dokumentasi Clang.
Secara desain, HWASan tidak memiliki zona merah berukuran terbatas seperti ASan untuk mendeteksi overflow atau karantina berkapasitas terbatas seperti ASan untuk mendeteksi penggunaan setelah pelepasan. Oleh karena itu, HWASan dapat mendeteksi bug terlepas dari seberapa besar overflow atau seberapa lama memori dibatalkan alokasinya. Hal ini memberi HWASan keuntungan besar dibandingkan ASan.
Namun, HWASan memiliki sejumlah nilai tag yang mungkin terbatas (256), yang berarti ada probabilitas 0,4% untuk tidak menemukan bug selama satu eksekusi program.
Persyaratan
Versi terbaru (4.14+) dari kernel Android umum mendukung HWASan 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 memerlukan kernel Linux untuk menerima pointer yang diberi tag dalam argumen panggilan sistem. Dukungan untuk hal ini diterapkan dalam patchset upstream berikut:
- ABI alamat bertag arm64
- arm64: hapus tag pointer pengguna yang diteruskan ke kernel
- mm: Hindari pembuatan alias alamat virtual di brk()/mmap()/mremap()
- arm64: Memvalidasi alamat yang diberi tag di access_ok() yang dipanggil dari thread kernel
Jika Anda membangun dengan toolchain kustom, pastikan toolchain tersebut mencakup 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 mempermudah, Anda dapat menambahkan setelan SANITIZE_TARGET ke definisi produk, mirip dengan aosp_coral_hwasan.
Bagi pengguna yang sudah terbiasa dengan AddressSanitizer, banyak kompleksitas build yang hilang:
- Tidak perlu menjalankan make dua kali.
- Build inkremental dapat langsung digunakan.
- Tidak perlu mem-flash userdata.
Beberapa batasan AddressSanitizer juga tidak ada lagi:
- Dukungan untuk file yang dapat dieksekusi statis.
- Anda dapat melewati sanitasi target selain libc. Tidak seperti ASan, tidak ada persyaratan bahwa jika library dibersihkan, maka semua yang dapat dieksekusi yang menautkannya juga harus dibersihkan.
Beralih antara image HWASan dan image biasa dengan nomor build yang sama (atau lebih tinggi) dapat dilakukan secara bebas. Perangkat tidak perlu dihapus total.
Untuk melewati pembersihan modul, gunakan
LOCAL_NOSANITIZE := hwaddress
(Android.mk) atau
sanitize: { hwaddress: false }
(Android.bp).
Membersihkan target individual
HWASan dapat diaktifkan per target dalam build reguler (tidak dibersihkan), 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 pembersihan libc memungkinkan pemberian tag pada alokasi memori heap di seluruh sistem, serta
pemeriksaan tag untuk operasi memori di dalam libc.so
. Hal ini dapat menangkap bug bahkan dalam biner
yang tidak mengaktifkan HWASan jika akses memori yang buruk ada di libc.so
(mis. pthread_mutex_unlock()
pada mutex yang delete()
.
Anda tidak perlu mengubah file build apa pun jika seluruh platform dibangun menggunakan HWASan.
Stack trace yang lebih baik
HWASan menggunakan unwinder berbasis frame pointer yang cepat untuk merekam stack
trace untuk setiap peristiwa alokasi dan dealokasi memori dalam
program. Android mengaktifkan pointer frame dalam kode AArch64 secara default,
sehingga ini berfungsi dengan baik dalam praktiknya. Jika Anda perlu membatalkan proses melalui
kode terkelola, tetapkan HWASAN_OPTIONS=fast_unwind_on_malloc=0
di lingkungan proses. Perhatikan bahwa stack akses memori yang buruk
menggunakan unwinder "lambat" secara default; setelan ini hanya memengaruhi
trace alokasi dan dealokasi. Opsi ini dapat sangat
membebani CPU, bergantung pada beban.
Simbolisasi
Lihat Simbolisasi di "Memahami laporan HWASan".
HWASan dalam aplikasi
Mirip dengan AddressSanitizer, HWASan tidak dapat melihat kode Java, tetapi HWASan dapat mendeteksi bug di library JNI. Hingga Android 14, menjalankan aplikasi HWASan di perangkat non-HWASan tidak didukung.
Di perangkat HWASan, aplikasi dapat diperiksa dengan HWASan dengan membuat
kode mereka 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.