בדומה למכשירי ה-sanitizer שמבוססים על LLVM לרכיבים במרחב המשתמש, Android כולל את Kernel Address Sanitizer (KASan). KASan הוא שילוב של שינויים בליבה ובזמן הידור, שמובילים ליצירת מערכת עם כלי מדידה שמאפשרת לזהות באגים ולנתח את שורש הבעיה בצורה פשוטה יותר.
KASan יכול לזהות סוגים רבים של הפרות זיכרון בליבה. הוא יכול גם לזהות קריאות וכתוביות מחוץ למגבלות ב-stack, ב-heap ובמשתנים גלובליים, וגם לזהות שימוש לאחר שחרור (use-after-free) ושחרורים כפולים.
בדומה ל-ASAN, KASan משתמש בשילוב של מכשירי מדידה של פונקציות זיכרון בזמן הידור וזיכרון צל כדי לעקוב אחרי הגישה לזיכרון בזמן הריצה. ב-KASan, שמונה חלקים ממרחב הזיכרון של הליבה מוקדשים לזיכרון צל, שמאפשר לקבוע אם גישה לזיכרון תקינה או לא.
יש תמיכה ב-KASan בארכיטקטורות x86_64 ו-arm64. הוא היה חלק מהליבה של Android מגרסה 4.0, והוא הועבר לגרסאות קודמות של ליבות מבוססי Android 3.18.
בנוסף ל-KASan, kcov הוא שינוי נוסף בליבה ששימושי לבדיקה. kcov פותח כדי לאפשר בדיקת fuzz מבוססת-כיסוי בליבה. הוא מודד את הכיסוי במונחים של קלט של syscall, והוא שימושי במערכות fuzzing, כמו syzkaller.
הטמעה
כדי לקמפל ליבה עם KASan ו-kcov מופעלים, מוסיפים את דגלי ה-build הבאים לתצורת ה-build של הליבה:
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
לאחר מכן, מפתחים את הליבה ומעבירים אותה (flash) כרגיל. הליבה של 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 בצורה נכונה במכשיר היעד.