[LINUX] Le désinfectant d'adresse de noyau (KASAN) (1/2)

À l'origine, il fait partie du code source du noyau Linux, il sera donc traité comme GPLv2 (reconnaissance qu'il devrait l'être).

https://www.kernel.org/doc/html/latest/index.html

Licensing documentation

The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.

https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing

https://www.kernel.org/doc/html/latest/dev-tools/kasan.html


Docs » Development tools for the kernel » The Kernel Address Sanitizer (KASAN)

The Kernel Address Sanitizer (KASAN)

Overview

KernelAddressSANitizer (KASAN) is a dynamic memory error detector designed to find out-of-bound and use-after-free bugs. KASAN has two modes: generic KASAN (similar to userspace ASan) and software tag-based KASAN (similar to userspace HWASan).

KernelAddressSANitizer (KASAN) est une méthode de détection dynamique des erreurs de mémoire. Il est conçu pour détecter les bogues hors limites et après utilisation libre. KASAN a deux modes. KASAN générique (similaire à l'espace utilisateur Asan) et KASAN basé sur des balises logicielles (similaire à l'espace utilisateur HWAsan).

KASAN uses compile-time instrumentation to insert validity checks before every memory access, and therefore requires a compiler version that supports that.

KASAN utilise des mesures de compilation pour la validation avant un accès complet à la mémoire. Et cela nécessite une version de compilateur prise en charge.

Generic KASAN is supported in both GCC and Clang. With GCC it requires version 4.9.2 or later for basic support and version 5.0 or later for detection of out-of-bounds accesses for stack and global variables and for inline instrumentation mode (see the Usage section). With Clang it requires version 7.0.0 or later and it doesn’t support detection of out-of-bounds accesses for global variables yet.

Generic KASAN est pris en charge par GCC et Clang. Pour GCC, la version 4.9.2 ou ultérieure est requise pour le support de base, la version 5.0 ou ultérieure est requise pour détecter les hors limites dans la pile et les variables globales, et le mode d'instrumentation en ligne est requis (voir la section Utilisation). S'il vous plaît). Pour Clang, les versions 7.0.0 et ultérieures sont requises, mais la détection hors limites pour les variables globales n'est pas encore prise en charge.

Tag-based KASAN is only supported in Clang and requires version 7.0.0 or later.

Le KASAN basé sur des balises est uniquement pris en charge dans Clang et nécessite la version 7.0.0 ou ultérieure.

Currently generic KASAN is supported for the x86_64, arm64, xtensa, s390 and riscv architectures, and tag-based KASAN is supported only for arm64.

Actuellement, le KASAN générique est pris en charge par les architectures x86_64, arm64, xtensa s390 et riscv. Et KASAN basé sur des balises n'est pris en charge que sur arm64.

Usage

To enable KASAN configure kernel with:

Les paramètres du noyau pour un frottement efficace de KASAN sont les suivants.

CONFIG_KASAN = y

and choose between CONFIG_KASAN_GENERIC (to enable generic KASAN) and CONFIG_KASAN_SW_TAGS (to enable software tag-based KASAN).

Sélectionnez ensuite CONFIG_KASAN_GENERIC (pour activer le KASAN générique) ou CONFIG_KASAN_SW_TAGS (pour activer le KASAN basé sur des balises logicielles).

You also need to choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline and inline are compiler instrumentation types. The former produces smaller binary while the latter is 1.1 - 2 times faster.

De plus, vous devez choisir entre CONFIG_KASAN_OUTLINE et CONFIG_LASAN_INLINE. Outline et Inline sont des types d'instrumentation de détresse. Le premier produit un petit binaire. Ce dernier est 1,1 à 2 fois plus rapide.

Both KASAN modes work with both SLUB and SLAB memory allocators. For better bug detection and nicer reporting, enable CONFIG_STACKTRACE.

Les deux modes KASAN peuvent être utilisés avec les allocateurs de mémoire SLUB et SLAB. Activez CONFIG_STACKTRACE pour une meilleure détection des bogues et de meilleurs rapports.

To augment reports with last allocation and freeing stack of the physical page, it is recommended to enable also CONFIG_PAGE_OWNER and boot with page_owner=on.

Pour étendre le rapport sur la pile finalement allouée / libérée sur la page physique, activez également CONFIF_PAGE_OWNER et définissez page_owner = on au démarrage.

To disable instrumentation for specific files or directories, add a line similar to the following to the respective kernel Makefile:

Pour désactiver l'instrumentation pour un fichier ou un répertoire particulier, ajoutez une ligne similaire à la suivante à chaque Makefile du noyau:

KASAN_SANITIZE_main.o := n

KASAN_SANITIZE := n


Error reports

A typical out-of-bounds access generic KASAN report looks like this:

Lors d'un accès hors limites typique, le KASAN générique signale comme suit.

==================================================================
BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0xa8/0xbc [test_kasan]
Write of size 1 at addr ffff8801f44ec37b by task insmod/2760

CPU: 1 PID: 2760 Comm: insmod Not tainted 4.19.0-rc3+ #698
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
Call Trace:
 dump_stack+0x94/0xd8
 print_address_description+0x73/0x280
 kasan_report+0x144/0x187
 __asan_report_store1_noabort+0x17/0x20
 kmalloc_oob_right+0xa8/0xbc [test_kasan]
 kmalloc_tests_init+0x16/0x700 [test_kasan]
 do_one_initcall+0xa5/0x3ae
 do_init_module+0x1b6/0x547
 load_module+0x75df/0x8070
 __do_sys_init_module+0x1c6/0x200
 __x64_sys_init_module+0x6e/0xb0
 do_syscall_64+0x9f/0x2c0
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7f96443109da
RSP: 002b:00007ffcf0b51b08 EFLAGS: 00000202 ORIG_RAX: 00000000000000af
RAX: ffffffffffffffda RBX: 000055dc3ee521a0 RCX: 00007f96443109da
RDX: 00007f96445cff88 RSI: 0000000000057a50 RDI: 00007f9644992000
RBP: 000055dc3ee510b0 R08: 0000000000000003 R09: 0000000000000000
R10: 00007f964430cd0a R11: 0000000000000202 R12: 00007f96445cff88
R13: 000055dc3ee51090 R14: 0000000000000000 R15: 0000000000000000

Allocated by task 2760:
 save_stack+0x43/0xd0
 kasan_kmalloc+0xa7/0xd0
 kmem_cache_alloc_trace+0xe1/0x1b0
 kmalloc_oob_right+0x56/0xbc [test_kasan]
 kmalloc_tests_init+0x16/0x700 [test_kasan]
 do_one_initcall+0xa5/0x3ae
 do_init_module+0x1b6/0x547
 load_module+0x75df/0x8070
 __do_sys_init_module+0x1c6/0x200
 __x64_sys_init_module+0x6e/0xb0
 do_syscall_64+0x9f/0x2c0
 entry_SYSCALL_64_after_hwframe+0x44/0xa9

Freed by task 815:
 save_stack+0x43/0xd0
 __kasan_slab_free+0x135/0x190
 kasan_slab_free+0xe/0x10
 kfree+0x93/0x1a0
 umh_complete+0x6a/0xa0
 call_usermodehelper_exec_async+0x4c3/0x640
 ret_from_fork+0x35/0x40

The buggy address belongs to the object at ffff8801f44ec300
 which belongs to the cache kmalloc-128 of size 128
The buggy address is located 123 bytes inside of
 128-byte region [ffff8801f44ec300, ffff8801f44ec380)
The buggy address belongs to the page:
page:ffffea0007d13b00 count:1 mapcount:0 mapping:ffff8801f7001640 index:0x0
flags: 0x200000000000100(slab)
raw: 0200000000000100 ffffea0007d11dc0 0000001a0000001a ffff8801f7001640
raw: 0000000000000000 0000000080150015 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff8801f44ec200: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
 ffff8801f44ec280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff8801f44ec300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
                                                                ^
 ffff8801f44ec380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
 ffff8801f44ec400: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
==================================================================

The header of the report provides a short summary of what kind of bug happened and what kind of access caused it. It’s followed by a stack trace of the bad access, a stack trace of where the accessed memory was allocated (in case bad access happens on a slab object), and a stack trace of where the object was freed (in case of a use-after-free bug report). Next comes a description of the accessed slab object and information about the accessed memory page.

La section d'en-tête du rapport fournit un bref résumé de ce qui n'a pas fonctionné et de quel type d'accès il s'agissait. Après cela, une trace de pile d'accès non autorisé, une trace de pile lorsque la mémoire accédée est sécurisée (lorsqu'il y a un accès non autorisé dans slab objct), et une trace de pile (bogue d'utilisation après la libération) lorsque l'objet est libéré. Dans le cas du rapport) suit. Ceci est suivi d'une description de l'objet de la dalle accédé et des informations sur la page mémoire accédée.

In the last section the report shows memory state around the accessed address. Reading this part requires some understanding of how KASAN works.

La dernière section montre l'état de la mémoire des ventes hebdomadaires d'adresse accédée. Pour lire cette partie, vous devez comprendre le fonctionnement de KASAN.

The state of each 8 aligned bytes of memory is encoded in one shadow byte. Those 8 bytes can be accessible, partially accessible, freed or be a redzone. We use the following encoding for each shadow byte:

We use different negative values to distinguish between different kinds of inaccessible memory like redzones or freed memory (see mm/kasan/kasan.h).

L'état de chaque 8 octet aligné en mémoire est codé dans un octet fantôme. Ces 8 octets peuvent être partiellement accédés, libérés ou redzonés. Utilisez le codage suivant pour chaque octet fantôme.

--0 signifie que vous pouvez accéder aux 8 octets de la zone mémoire correspondante. --number N (1 <= N <= 7) signifie que les N premiers octets sont accessibles et les autres (8-N) octets ne le sont pas.

In the report above the arrows point to the shadow byte 03, which means that the accessed address is partially accessible.

Dans le rapport ci-dessus, la flèche pointe vers l'octet d'ombre 03. Cela signifie que l'adresse accédée est partiellement accessible.

For tag-based KASAN this last report section shows the memory tags around the accessed address (see Implementation details section).

Dans le KASAN basé sur des balises, le rapport final montre les balises de mémoire autour de l'adresse consultée (voir la section Détails de l'implémentation).

Recommended Posts

Le désinfectant d'adresses du noyau (KASAN) (2/2)
Le désinfectant d'adresse de noyau (KASAN) (1/2)
Essayez le mécanisme de verrouillage du noyau Linux
Obtenir une adresse à partir d'un code postal