Désinfectant d'adresse de noyau (KASan)

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.