Kernel AddressSanitizer

उपयोगकर्ता स्पेस कॉम्पोनेंट के लिए LLVM पर आधारित सैनिटाइज़र की तरह ही, Android में कर्नल 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 को सही तरीके से चालू किया हो.