على غرار أدوات التنظيف المستندة إلى LLVM لمكوّنات مساحة المستخدم، يتضمّن Android أداة Kernel AddressSanitizer (KASan). KASan هي مزيج من تعديلات وقت التشغيل ووقت الترجمة البرمجية في النواة، ما يؤدي إلى نظام مزوّد بأدوات تسمح باكتشاف الأخطاء وتحليل الأسباب الجذرية بشكل أبسط.
يمكن لأداة KASan رصد العديد من أنواع انتهاكات الذاكرة في النواة. ويمكنه أيضًا رصد عمليات القراءة والكتابة خارج الحدود في المتغيرات المكدّسة والمتراكمة والعامة، كما يمكنه رصد عمليات الاستخدام بعد التحرير وعمليات التحرير المزدوجة.
على غرار ASan، تستخدم KASan مزيجًا من أدوات قياس أداء وظائف الذاكرة في وقت الترجمة البرمجية والذاكرة الوهمية لتتبُّع عمليات الوصول إلى الذاكرة في وقت التشغيل. في KASan، يتم تخصيص ثُمن مساحة ذاكرة النواة لذاكرة الظل التي تحدد ما إذا كان الوصول إلى الذاكرة صالحًا أم لا.
تتوفّر KASan على بنية x86_64 وarm64. وهي جزء من نواة المصدر منذ الإصدار 4.0، وتمت إعادة نقلها إلى النواة المستندة إلى Android 3.18.
بالإضافة إلى KASan، هناك تعديل آخر على النواة وهو kcov، وهو مفيد للاختبار. تم تطوير kcov للسماح بإجراء اختبارات غامضة موجّهة بالتغطية في النواة. ويقيس التغطية من حيث مدخلات استدعاءات النظام، وهو مفيد مع أنظمة التشويش، مثل 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 بشكل صحيح على جهاز الاختبار.