ضد عفونی کننده آدرس هسته (KASan)

مشابه ضدعفونی‌کننده‌های مبتنی بر LLVM برای اجزای فضای کاربران، اندروید شامل ضدعفونی‌کننده آدرس هسته (KASAN) است. KASAN ترکیبی از تغییرات زمان هسته و کامپایل است که منجر به یک سیستم ابزاری می شود که امکان کشف اشکال ساده تر و تجزیه و تحلیل علت ریشه را فراهم می کند.

KASAN می تواند بسیاری از انواع نقض حافظه را در هسته شناسایی کند. همچنین می‌تواند خواندن و نوشتن خارج از کران را روی متغیرهای پشته، هیپ و سراسری تشخیص دهد و می‌تواند آزادسازی پس از استفاده و دو برابر را تشخیص دهد.

مانند ASAN، KASAN از ترکیب ابزار دقیق عملکرد حافظه در زمان کامپایل و حافظه سایه برای ردیابی دسترسی‌های حافظه در زمان اجرا استفاده می‌کند. در KASAN، یک هشتم فضای حافظه هسته به حافظه سایه اختصاص داده شده است، که تعیین می کند آیا دسترسی به حافظه معتبر است یا خیر.

KASAN در معماری های x86_64 و arm64 پشتیبانی می شود. از نسخه 4.0 بخشی از هسته بالادست بوده و به هسته های مبتنی بر اندروید 3.18 بکپورت شده است.

علاوه بر KASAN، kcov یکی دیگر از اصلاحات هسته است که برای آزمایش مفید است. kcov برای امکان تست فاز هدایت شده با پوشش در هسته توسعه داده شد. این پوشش را از نظر ورودی های syscall اندازه گیری می کند و برای سیستم های فازی مانند syzkaller مفید است.

پیاده سازی

برای کامپایل یک هسته با KASAN و kcov فعال، پرچم های ساخت زیر را به پیکربندی ساخت هسته خود اضافه کنید:

CONFIG_KASAN
CONFIG_KASAN_INLINE
CONFIG_TEST_KASAN
CONFIG_KCOV
CONFIG_SLUB
CONFIG_SLUB_DEBUG
CONFIG_CC_OPTIMIZE_FOR_SIZE

و حذف موارد زیر:

CONFIG_SLUB_DEBUG_ON
CONFIG_SLUB_DEBUG_PANIC_ON
CONFIG_KASAN_OUTLINE
CONFIG_KERNEL_LZ4

سپس طبق معمول کرنل خود را بسازید و فلش کنید. هسته KASAN به طور قابل توجهی بزرگتر از اصلی است. در صورت نیاز، هر پارامتر بوت و تنظیمات بوت لودر را تغییر دهید تا این مورد در نظر گرفته شود.

پس از فلش کردن کرنل، لاگ های بوت هسته را بررسی کنید تا ببینید آیا KASAN فعال و اجرا می شود یا خیر. هسته با اطلاعات نقشه حافظه برای KASAN راه اندازی می شود، مانند:

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

و یک باگ اینگونه به نظر می رسد:

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

علاوه بر این، اگر ماژول ها در هسته شما فعال هستند، می توانید ماژول هسته test_kasan را برای آزمایش بیشتر بارگذاری کنید. ماژول تلاش می کند تا به حافظه خارج از محدوده دسترسی داشته باشد و از آن استفاده رایگان کند و برای اطمینان از اینکه شما به درستی KASan را در دستگاه مورد نظر فعال کرده اید مفید است.