Comme les sanitizers basés sur LLVM pour les composants de l'espace utilisateur, Android inclut le Kernel AddressSanitizer (KASan). KASan est une combinaison de modifications du noyau et du temps de compilation qui aboutit à un système instrumenté permettant de simplifier la découverte des bugs et l'analyse des causes fondamentales.
KASan peut détecter de nombreux types de violations de mémoire dans le noyau. Il peut également détecter les lectures et écritures hors limites sur les variables de pile, de tas et globales, ainsi que les utilisations après libération et les doubles libérations.
Comme ASan, KASan utilise une combinaison d'instrumentation de fonction de mémoire au moment de la compilation et de mémoire fantôme pour suivre les accès mémoire au moment de l'exécution. Dans KASan, un huitième de l'espace mémoire du noyau est dédié à la mémoire fantôme, qui détermine si un accès mémoire est valide ou non.
KASan est compatible avec les architectures x86_64 et arm64. Il fait partie du noyau en amont depuis la version 4.0 et a été rétroporté vers les noyaux basés sur Android 3.18.
En plus de KASan, kcov est une autre modification du noyau utile pour les tests. kcov a été développé pour permettre les tests fuzzing guidés par la couverture dans le noyau. Il mesure la couverture en termes d'entrées d'appels système et est utile avec les systèmes de fuzzing, tels que syzkaller.
Implémentation
Pour compiler un noyau avec KASan et kcov activés, ajoutez les options de compilation suivantes à la configuration de compilation de votre noyau :
CONFIG_KASAN CONFIG_KASAN_INLINE CONFIG_TEST_KASAN CONFIG_KCOV CONFIG_SLUB CONFIG_SLUB_DEBUG CONFIG_CC_OPTIMIZE_FOR_SIZE
Et supprimez les éléments suivants :
CONFIG_SLUB_DEBUG_ON CONFIG_SLUB_DEBUG_PANIC_ON CONFIG_KASAN_OUTLINE CONFIG_KERNEL_LZ4
Compilez et flashez ensuite votre noyau comme d'habitude. Le noyau KASan est considérablement plus volumineux que l'original. Si nécessaire, modifiez les paramètres de démarrage et les paramètres du bootloader pour en tenir compte.
Après avoir flashé le noyau, consultez les journaux de démarrage du noyau pour voir si KASan est activé et en cours d'exécution. Le noyau démarre avec des informations sur la carte mémoire pour KASan, telles que :
... [ 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) ...
Voici à quoi ressemble un bug :
[ 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 ==================================================================
De plus, si les modules sont activés dans votre noyau, vous pouvez charger le module de noyau test_kasan pour effectuer des tests supplémentaires. Le module tente d'accéder à la mémoire hors limites et d'utiliser après libération. Il est utile pour vous assurer que vous avez correctement activé KASan sur un appareil cible.