Pembersih Alamat Kernel (KASan)

Mirip dengan pembersih berbasis LLVM untuk komponen ruang pengguna, Android menyertakan Kernel Address Sanitizer (KASAN). KASAN adalah kombinasi modifikasi kernel dan waktu kompilasi yang menghasilkan sistem terinstrumentasi yang memungkinkan penemuan bug dan analisis akar penyebab lebih sederhana.

KASAN dapat mendeteksi berbagai jenis pelanggaran memori di kernel. Ini juga dapat mendeteksi pembacaan dan penulisan di luar batas pada variabel tumpukan, heap, dan global, serta dapat mendeteksi penggunaan setelah bebas dan pembebasan ganda.

Mirip dengan ASAN, KASAN menggunakan kombinasi instrumentasi fungsi memori pada waktu kompilasi dan memori bayangan untuk melacak akses memori pada waktu proses. Di KASAN, seperdelapan ruang memori kernel didedikasikan untuk memori bayangan, yang menentukan apakah akses memori valid atau tidak.

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

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

Penerapan

Untuk mengkompilasi kernel dengan KASAN dan kcov yang 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 yang berikut ini:

CONFIG_SLUB_DEBUG_ON
CONFIG_SLUB_DEBUG_PANIC_ON
CONFIG_KASAN_OUTLINE
CONFIG_KERNEL_LZ4

Kemudian build dan flash kernel Anda seperti biasa. Kernel KASAN jauh lebih besar dari aslinya. Jika perlu, ubah parameter boot dan pengaturan bootloader apa pun untuk mempertimbangkan hal ini.

Setelah mem-flash kernel, periksa log boot kernel untuk melihat apakah KASAN diaktifkan dan dijalankan. Kernel akan memulai 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 bugnya:

[   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, Anda dapat memuat modul kernel test_kasan untuk pengujian lebih lanjut. Modul ini mencoba mengakses memori di luar batas dan menggunakan setelah bebas dan berguna untuk memastikan Anda mengaktifkan KASan dengan benar pada perangkat target.