Kernel Address Sanitizer

Serupa dengan sanitizer berbasis LLVM untuk komponen ruang pengguna, Android menyertakan Kernel Address Sanitizer (KASan). KASan adalah kombinasi kernel dan modifikasi waktu kompilasi yang menghasilkan sistem berinstrumen yang memungkinkan penemuan bug dan analisis akar masalah yang lebih sederhana.

KASan dapat mendeteksi banyak jenis pelanggaran memori di kernel. Alat ini juga dapat mendeteksi pembacaan dan penulisan di luar batas pada stack, heap, dan variabel global, serta dapat mendeteksi penggunaan setelah bebas dan bebas ganda.

Serupa dengan ASan, KASan menggunakan kombinasi instrumentasi fungsi memori pada waktu kompilasi dan memori bayangan untuk melacak akses memori saat runtime. Di KASan, delapan dari ruang memori kernel dikhususkan untuk memori bayangan, yang menentukan apakah akses memori valid atau tidak.

KASan didukung pada arsitektur x86_64 dan arm64. Fitur ini telah menjadi bagian dari kernel upstream sejak 4.0, dan telah di-backport ke kernel berbasis Android 3.18.

Selain KASan, kcov adalah modifikasi kernel lain yang berguna untuk pengujian. kcov dikembangkan untuk memungkinkan pengujian fuzz yang dipandu cakupan di kernel. Alat ini mengukur cakupan dalam hal input syscall dan berguna dengan sistem fuzzing, seperti syzkaller.

Implementasi

Untuk mengompilasi kernel dengan KASan dan kcov diaktifkan, tambahkan flag build berikut ke konfigurasi build kernel Anda:

CONFIG_KASAN
CONFIG_KASAN_INLINE
CONFIG_TEST_KASAN
CONFIG_KCOV
CONFIG_SLUB
CONFIG_SLUB_DEBUG
CONFIG_CC_OPTIMIZE_FOR_SIZE

Dan menghapus hal berikut:

CONFIG_SLUB_DEBUG_ON
CONFIG_SLUB_DEBUG_PANIC_ON
CONFIG_KASAN_OUTLINE
CONFIG_KERNEL_LZ4

Kemudian, build dan flash kernel seperti biasa. Kernel KASan jauh lebih besar daripada kernel asli. Jika perlu, ubah parameter booting dan setelan bootloader untuk mempertimbangkan hal ini.

Setelah mem-flash kernel, periksa log booting kernel untuk melihat apakah KASan diaktifkan dan berjalan. Kernel akan dimulai dengan informasi peta memori untuk KASan, seperti:

...
[    0.000000] c0      0 Virtual kernel memory layout:
[    0.000000] c0      0     kasan   : 0xffffff8000000000 - 0xffffff9000000000   (    64 GB)
[    0.000000] c0      0     vmalloc : 0xffffff9000010000 - 0xffffffbdbfff0000   (   182 GB)
[    0.000000] c0      0     vmemmap : 0xffffffbdc0000000 - 0xffffffbfc0000000   (     8 GB maximum)
[    0.000000] c0      0               0xffffffbdc0000000 - 0xffffffbdc3f95400   (    63 MB actual)
[    0.000000] c0      0     PCI I/O : 0xffffffbffa000000 - 0xffffffbffb000000   (    16 MB)
[    0.000000] c0      0     fixed   : 0xffffffbffbdfd000 - 0xffffffbffbdff000   (     8 KB)
[    0.000000] c0      0     modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
[    0.000000] c0      0     memory  : 0xffffffc000000000 - 0xffffffc0fe550000   (  4069 MB)
[    0.000000] c0      0       .init : 0xffffffc001d33000 - 0xffffffc001dce000   (   620 KB)
[    0.000000] c0      0       .text : 0xffffffc000080000 - 0xffffffc001d32284   ( 29385 KB)
...

Dan beginilah tampilan bug:

[   18.539668] c3      1 ==================================================================
[   18.547662] c3      1 BUG: KASAN: null-ptr-deref on address 0000000000000008
[   18.554689] c3      1 Read of size 8 by task swapper/0/1
[   18.559988] c3      1 CPU: 3 PID: 1 Comm: swapper/0 Tainted: G        W      3.18.24-xxx #1
[   18.569275] c3      1 Hardware name: Android Device
[   18.577433] c3      1 Call trace:
[   18.580739] c3      1 [<ffffffc00008b32c>] dump_backtrace+0x0/0x2c4
[   18.586985] c3      1 [<ffffffc00008b600>] show_stack+0x10/0x1c
[   18.592889] c3      1 [<ffffffc001481194>] dump_stack+0x74/0xc8
[   18.598792] c3      1 [<ffffffc000202ee0>] kasan_report+0x11c/0x4d0
[   18.605038] c3      1 [<ffffffc00020286c>] __asan_load8+0x20/0x80
[   18.611115] c3      1 [<ffffffc000bdefe8>] android_verity_ctr+0x8cc/0x1024
[   18.617976] c3      1 [<ffffffc000bcaa2c>] dm_table_add_target+0x3dc/0x50c
[   18.624832] c3      1 [<ffffffc001bdbe60>] dm_run_setup+0x50c/0x678
[   18.631082] c3      1 [<ffffffc001bda8c0>] prepare_namespace+0x44/0x1ac
[   18.637676] c3      1 [<ffffffc001bda170>] kernel_init_freeable+0x328/0x364
[   18.644625] c3      1 [<ffffffc001478e20>] kernel_init+0x10/0xd8
[   18.650613] c3      1 ==================================================================

Selain itu, jika modul diaktifkan di kernel, Anda dapat memuat modul kernel test_kasan untuk pengujian lebih lanjut. Modul ini mencoba akses memori di luar batas dan penggunaan setelah bebas serta berguna untuk memastikan Anda mengaktifkan KASan dengan benar di perangkat target.