Bộ khử trùng địa chỉ hạt nhân (KASan)

Tương tự như công cụ khử trùng dựa trên LLVM dành cho các thành phần không gian người dùng, Android bao gồm Trình khử trùng địa chỉ hạt nhân (KASAN). KASAN là sự kết hợp giữa các sửa đổi về nhân và thời gian biên dịch để tạo ra một hệ thống được trang bị công cụ cho phép phát hiện lỗi và phân tích nguyên nhân gốc rễ đơn giản hơn.

KASAN có thể phát hiện nhiều loại vi phạm bộ nhớ trong kernel. Nó cũng có thể phát hiện các lần đọc và ghi ngoài giới hạn trên các biến ngăn xếp, vùng heap và toàn cục, đồng thời có thể phát hiện các lần sử dụng sau khi miễn phí và giải phóng gấp đôi.

Tương tự như ASAN, KASAN sử dụng kết hợp công cụ đo chức năng bộ nhớ tại thời điểm biên dịch và bộ nhớ ẩn để theo dõi các lần truy cập bộ nhớ trong thời gian chạy. Trong KASAN, một phần tám không gian bộ nhớ kernel được dành riêng cho bộ nhớ tối, xác định xem quyền truy cập bộ nhớ có hợp lệ hay không.

KASAN được hỗ trợ trên kiến ​​trúc x86_64 và arm64. Nó đã là một phần của hạt nhân ngược dòng kể từ phiên bản 4.0 và đã được chuyển sang hạt nhân dựa trên Android 3.18.

Ngoài KASAN, kcov là một bản sửa đổi kernel khác hữu ích cho việc thử nghiệm. kcov được phát triển để cho phép kiểm tra fuzz theo hướng dẫn trong kernel. Nó đo lường mức độ bao phủ theo đầu vào tòa nhà và rất hữu ích với các hệ thống làm mờ, chẳng hạn như syzkaller .

Thực hiện

Để biên dịch kernel đã bật KASAN và kcov, hãy thêm các cờ xây dựng sau vào cấu hình bản dựng kernel của bạn:

CONFIG_KASAN
CONFIG_KASAN_INLINE
CONFIG_TEST_KASAN
CONFIG_KCOV
CONFIG_SLUB
CONFIG_SLUB_DEBUG
CONFIG_CC_OPTIMIZE_FOR_SIZE

Và loại bỏ những điều sau đây:

CONFIG_SLUB_DEBUG_ON
CONFIG_SLUB_DEBUG_PANIC_ON
CONFIG_KASAN_OUTLINE
CONFIG_KERNEL_LZ4

Sau đó build và flash kernel của bạn như bình thường. Hạt nhân KASAN lớn hơn đáng kể so với hạt nhân gốc. Nếu cần, hãy sửa đổi mọi tham số khởi động và cài đặt bộ nạp khởi động để xem xét điều này.

Sau khi flash kernel, hãy kiểm tra nhật ký khởi động kernel để xem KASAN đã được bật và chạy chưa. Kernel sẽ khởi động với thông tin bản đồ bộ nhớ cho KASAN, chẳng hạn như:

...
[    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)
...

Và đây là cách một lỗi sẽ trông như thế nào:

[   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 ==================================================================

Ngoài ra, nếu các mô-đun được bật trong hạt nhân của bạn, bạn có thể tải mô-đun hạt nhân test_kasan để thử nghiệm thêm. Mô-đun này thử truy cập bộ nhớ ngoài giới hạn và không sử dụng sau này, đồng thời rất hữu ích để đảm bảo bạn đã bật KASan chính xác trên thiết bị mục tiêu.