Semblable aux désinfectants basés sur LLVM pour les composants de l'espace utilisateur, Android inclut le Kernel Address Sanitizer (KASAN). KASAN est une combinaison de modifications du noyau et de la compilation qui aboutissent à un système instrumenté permettant une découverte plus simple des bogues et une analyse des causes profondes.
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 la pile, le tas et les variables globales, ainsi que les utilisations après libération et les doubles libérations.
Semblable à ASAN, KASAN utilise une combinaison d'instruments de fonction de mémoire au moment de la compilation et de mémoire fantôme pour suivre les accès à la 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 pris en charge sur 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 des tests de fuzz 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 .
Mise en œuvre
Pour compiler un noyau avec KASAN et kcov activés, ajoutez les indicateurs de build suivants à la configuration de build de votre noyau :
CONFIG_KASAN CONFIG_KASAN_INLINE CONFIG_TEST_KASAN CONFIG_KCOV CONFIG_SLUB CONFIG_SLUB_DEBUG CONFIG_CC_OPTIMIZE_FOR_SIZE
Et en supprimant les éléments suivants :
CONFIG_SLUB_DEBUG_ON CONFIG_SLUB_DEBUG_PANIC_ON CONFIG_KASAN_OUTLINE CONFIG_KERNEL_LZ4
Ensuite, construisez et flashez votre noyau comme d'habitude. Le noyau KASAN est considérablement plus gros que l'original. Si nécessaire, modifiez les paramètres de démarrage et les paramètres du chargeur de démarrage pour en tenir compte.
Après avoir flashé le noyau, vérifiez les journaux de démarrage du noyau pour voir si KASAN est activé et en cours d'exécution. Le noyau démarrera avec les informations de 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) ...
Et voici à quoi ressemblera 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 du noyau test_kasan pour des tests plus approfondis. Le module tente des accès à la mémoire hors limites et une utilisation après libération et est utile pour garantir que vous avez correctement activé KASan sur un appareil cible.