← Documents Documentation/dev-tools/kasan.rst GitHub 원문 ↗

Linux 6.18.37 · Dev Tools

Kernel Address Sanitizer (KASAN)

Generic·software tag·hardware tag KASAN의 지원 범위, boot 정책, report 해석, shadow memory 구현, 검사 제외 방법과 KUnit test를 설명합니다.

Source pathDocumentation/dev-tools/kasan.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

kasan.rst:1-571

KASAN은 out-of-bounds와 use-after-free를 실행 중에 탐지합니다. Generic mode는 정밀한 debugging에, software tag mode는 arm64 test workload에, MTE 기반 hardware tag mode는 낮은 overhead가 필요한 production 탐지와 mitigation에 적합합니다.

mode마다 지원 memory와 compiler 요구 사항, report 정밀도, overhead가 다릅니다. 실제 운용에서는 panic·stack trace·sampling parameter를 목적에 맞게 정하고, report의 access stack과 allocation/free stack, shadow byte 또는 memory tag를 함께 해석해야 합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2 .. Copyright (C) 2023, Google LLC.
3
4 Kernel Address Sanitizer (KASAN)
5 ================================
6
7 Overview
8 --------
9
10 Kernel Address Sanitizer (KASAN) is a dynamic memory safety error detector
11 designed to find out-of-bounds and use-after-free bugs.
12
13 KASAN has three modes:
14
15 1. Generic KASAN
16 2. Software Tag-Based KASAN
17 3. Hardware Tag-Based KASAN
18
19 Generic KASAN, enabled with CONFIG_KASAN_GENERIC, is the mode intended for
20 debugging, similar to userspace ASan. This mode is supported on many CPU
21 architectures, but it has significant performance and memory overheads.
22
23 Software Tag-Based KASAN or SW_TAGS KASAN, enabled with CONFIG_KASAN_SW_TAGS,
24 can be used for both debugging and dogfood testing, similar to userspace HWASan.
25 This mode is only supported for arm64, but its moderate memory overhead allows
26 using it for testing on memory-restricted devices with real workloads.
27
28 Hardware Tag-Based KASAN or HW_TAGS KASAN, enabled with CONFIG_KASAN_HW_TAGS,
29 is the mode intended to be used as an in-field memory bug detector or as a
30 security mitigation. This mode only works on arm64 CPUs that support MTE
31 (Memory Tagging Extension), but it has low memory and performance overheads and
32 thus can be used in production.
33
34 For details about the memory and performance impact of each KASAN mode, see the
35 descriptions of the corresponding Kconfig options.
36
37 The Generic and the Software Tag-Based modes are commonly referred to as the
38 software modes. The Software Tag-Based and the Hardware Tag-Based modes are
39 referred to as the tag-based modes.
40
41 Support
42 -------
43
44 Architectures
45 ~~~~~~~~~~~~~
46
47 Generic KASAN is supported on x86_64, arm, arm64, powerpc, riscv, s390, xtensa,
48 and loongarch, and the tag-based KASAN modes are supported only on arm64.
49
50 Compilers
51 ~~~~~~~~~
52
53 Software KASAN modes use compile-time instrumentation to insert validity checks
54 before every memory access and thus require a compiler version that provides
55 support for that. The Hardware Tag-Based mode relies on hardware to perform
56 these checks but still requires a compiler version that supports the memory
57 tagging instructions.
58
59 Generic KASAN requires GCC version 8.3.0 or later
60 or any Clang version supported by the kernel.
61
62 Software Tag-Based KASAN requires GCC 11+
63 or any Clang version supported by the kernel.
64
65 Hardware Tag-Based KASAN requires GCC 10+ or Clang 12+.
66
67 Memory types
68 ~~~~~~~~~~~~
69
70 Generic KASAN supports finding bugs in all of slab, page_alloc, vmap, vmalloc,
71 stack, and global memory.
72
73 Software Tag-Based KASAN supports slab, page_alloc, vmalloc, and stack memory.
74
75 Hardware Tag-Based KASAN supports slab, page_alloc, and non-executable vmalloc
76 memory.
77
78 For slab, both software KASAN modes support SLUB and SLAB allocators, while
79 Hardware Tag-Based KASAN only supports SLUB.
80
81 Usage
82 -----
83
84 To enable KASAN, configure the kernel with::
85
86 CONFIG_KASAN=y
87
88 and choose between ``CONFIG_KASAN_GENERIC`` (to enable Generic KASAN),
89 ``CONFIG_KASAN_SW_TAGS`` (to enable Software Tag-Based KASAN), and
90 ``CONFIG_KASAN_HW_TAGS`` (to enable Hardware Tag-Based KASAN).
91
92 For the software modes, also choose between ``CONFIG_KASAN_OUTLINE`` and
93 ``CONFIG_KASAN_INLINE``. Outline and inline are compiler instrumentation types.
94 The former produces a smaller binary while the latter is up to 2 times faster.
95
96 To include alloc and free stack traces of affected slab objects into reports,
97 enable ``CONFIG_STACKTRACE``. To include alloc and free stack traces of affected
98 physical pages, enable ``CONFIG_PAGE_OWNER`` and boot with ``page_owner=on``.
99
100 Boot parameters
101 ~~~~~~~~~~~~~~~
102
103 KASAN is affected by the generic ``panic_on_warn`` command line parameter.
104 When it is enabled, KASAN panics the kernel after printing a bug report.
105
106 By default, KASAN prints a bug report only for the first invalid memory access.
107 With ``kasan_multi_shot``, KASAN prints a report on every invalid access. This
108 effectively disables ``panic_on_warn`` for KASAN reports.
109
110 Alternatively, independent of ``panic_on_warn``, the ``kasan.fault=`` boot
111 parameter can be used to control panic and reporting behaviour:
112
113 - ``kasan.fault=report``, ``=panic``, or ``=panic_on_write`` controls whether
114 to only print a KASAN report, panic the kernel, or panic the kernel on
115 invalid writes only (default: ``report``). The panic happens even if
116 ``kasan_multi_shot`` is enabled. Note that when using asynchronous mode of
117 Hardware Tag-Based KASAN, ``kasan.fault=panic_on_write`` always panics on
118 asynchronously checked accesses (including reads).
119
120 Software and Hardware Tag-Based KASAN modes (see the section about various
121 modes below) support altering stack trace collection behavior:
122
123 - ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
124 traces collection (default: ``on``).
125 - ``kasan.stack_ring_size=<number of entries>`` specifies the number of entries
126 in the stack ring (default: ``32768``).
127
128 Hardware Tag-Based KASAN mode is intended for use in production as a security
129 mitigation. Therefore, it supports additional boot parameters that allow
130 disabling KASAN altogether or controlling its features:
131
132 - ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``).
133
134 - ``kasan.mode=sync``, ``=async`` or ``=asymm`` controls whether KASAN
135 is configured in synchronous, asynchronous or asymmetric mode of
136 execution (default: ``sync``).
137 Synchronous mode: a bad access is detected immediately when a tag
138 check fault occurs.
139 Asynchronous mode: a bad access detection is delayed. When a tag check
140 fault occurs, the information is stored in hardware (in the TFSR_EL1
141 register for arm64). The kernel periodically checks the hardware and
142 only reports tag faults during these checks.
143 Asymmetric mode: a bad access is detected synchronously on reads and
144 asynchronously on writes.
145
146 - ``kasan.write_only=off`` or ``kasan.write_only=on`` controls whether KASAN
147 checks the write (store) accesses only or all accesses (default: ``off``).
148
149 - ``kasan.vmalloc=off`` or ``=on`` disables or enables tagging of vmalloc
150 allocations (default: ``on``).
151
152 - ``kasan.page_alloc.sample=<sampling interval>`` makes KASAN tag only every
153 Nth page_alloc allocation with the order equal or greater than
154 ``kasan.page_alloc.sample.order``, where N is the value of the ``sample``
155 parameter (default: ``1``, or tag every such allocation).
156 This parameter is intended to mitigate the performance overhead introduced
157 by KASAN.
158 Note that enabling this parameter makes Hardware Tag-Based KASAN skip checks
159 of allocations chosen by sampling and thus miss bad accesses to these
160 allocations. Use the default value for accurate bug detection.
161
162 - ``kasan.page_alloc.sample.order=<minimum page order>`` specifies the minimum
163 order of allocations that are affected by sampling (default: ``3``).
164 Only applies when ``kasan.page_alloc.sample`` is set to a value greater
165 than ``1``.
166 This parameter is intended to allow sampling only large page_alloc
167 allocations, which is the biggest source of the performance overhead.
168
169 Error reports
170 ~~~~~~~~~~~~~
171
172 A typical KASAN report looks like this::
173
174 ==================================================================
175 BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0xa8/0xbc [kasan_test]
176 Write of size 1 at addr ffff8801f44ec37b by task insmod/2760
177
178 CPU: 1 PID: 2760 Comm: insmod Not tainted 4.19.0-rc3+ #698
179 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
180 Call Trace:
181 dump_stack+0x94/0xd8
182 print_address_description+0x73/0x280
183 kasan_report+0x144/0x187
184 __asan_report_store1_noabort+0x17/0x20
185 kmalloc_oob_right+0xa8/0xbc [kasan_test]
186 kmalloc_tests_init+0x16/0x700 [kasan_test]
187 do_one_initcall+0xa5/0x3ae
188 do_init_module+0x1b6/0x547
189 load_module+0x75df/0x8070
190 __do_sys_init_module+0x1c6/0x200
191 __x64_sys_init_module+0x6e/0xb0
192 do_syscall_64+0x9f/0x2c0
193 entry_SYSCALL_64_after_hwframe+0x44/0xa9
194 RIP: 0033:0x7f96443109da
195 RSP: 002b:00007ffcf0b51b08 EFLAGS: 00000202 ORIG_RAX: 00000000000000af
196 RAX: ffffffffffffffda RBX: 000055dc3ee521a0 RCX: 00007f96443109da
197 RDX: 00007f96445cff88 RSI: 0000000000057a50 RDI: 00007f9644992000
198 RBP: 000055dc3ee510b0 R08: 0000000000000003 R09: 0000000000000000
199 R10: 00007f964430cd0a R11: 0000000000000202 R12: 00007f96445cff88
200 R13: 000055dc3ee51090 R14: 0000000000000000 R15: 0000000000000000
201
202 Allocated by task 2760:
203 save_stack+0x43/0xd0
204 kasan_kmalloc+0xa7/0xd0
205 kmem_cache_alloc_trace+0xe1/0x1b0
206 kmalloc_oob_right+0x56/0xbc [kasan_test]
207 kmalloc_tests_init+0x16/0x700 [kasan_test]
208 do_one_initcall+0xa5/0x3ae
209 do_init_module+0x1b6/0x547
210 load_module+0x75df/0x8070
211 __do_sys_init_module+0x1c6/0x200
212 __x64_sys_init_module+0x6e/0xb0
213 do_syscall_64+0x9f/0x2c0
214 entry_SYSCALL_64_after_hwframe+0x44/0xa9
215
216 Freed by task 815:
217 save_stack+0x43/0xd0
218 __kasan_slab_free+0x135/0x190
219 kasan_slab_free+0xe/0x10
220 kfree+0x93/0x1a0
221 umh_complete+0x6a/0xa0
222 call_usermodehelper_exec_async+0x4c3/0x640
223 ret_from_fork+0x35/0x40
224
225 The buggy address belongs to the object at ffff8801f44ec300
226 which belongs to the cache kmalloc-128 of size 128
227 The buggy address is located 123 bytes inside of
228 128-byte region [ffff8801f44ec300, ffff8801f44ec380)
229 The buggy address belongs to the page:
230 page:ffffea0007d13b00 count:1 mapcount:0 mapping:ffff8801f7001640 index:0x0
231 flags: 0x200000000000100(slab)
232 raw: 0200000000000100 ffffea0007d11dc0 0000001a0000001a ffff8801f7001640
233 raw: 0000000000000000 0000000080150015 00000001ffffffff 0000000000000000
234 page dumped because: kasan: bad access detected
235
236 Memory state around the buggy address:
237 ffff8801f44ec200: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
238 ffff8801f44ec280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
239 >ffff8801f44ec300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
240 ^
241 ffff8801f44ec380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
242 ffff8801f44ec400: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
243 ==================================================================
244
245 The report header summarizes what kind of bug happened and what kind of access
246 caused it. It is followed by a stack trace of the bad access, a stack trace of
247 where the accessed memory was allocated (in case a slab object was accessed),
248 and a stack trace of where the object was freed (in case of a use-after-free
249 bug report). Next comes a description of the accessed slab object and the
250 information about the accessed memory page.
251
252 In the end, the report shows the memory state around the accessed address.
253 Internally, KASAN tracks memory state separately for each memory granule, which
254 is either 8 or 16 aligned bytes depending on KASAN mode. Each number in the
255 memory state section of the report shows the state of one of the memory
256 granules that surround the accessed address.
257
258 For Generic KASAN, the size of each memory granule is 8. The state of each
259 granule is encoded in one shadow byte. Those 8 bytes can be accessible,
260 partially accessible, freed, or be a part of a redzone. KASAN uses the following
261 encoding for each shadow byte: 00 means that all 8 bytes of the corresponding
262 memory region are accessible; number N (1 <= N <= 7) means that the first N
263 bytes are accessible, and other (8 - N) bytes are not; any negative value
264 indicates that the entire 8-byte word is inaccessible. KASAN uses different
265 negative values to distinguish between different kinds of inaccessible memory
266 like redzones or freed memory (see mm/kasan/kasan.h).
267
268 In the report above, the arrow points to the shadow byte ``03``, which means
269 that the accessed address is partially accessible.
270
271 For tag-based KASAN modes, this last report section shows the memory tags around
272 the accessed address (see the `Implementation details`_ section).
273
274 Note that KASAN bug titles (like ``slab-out-of-bounds`` or ``use-after-free``)
275 are best-effort: KASAN prints the most probable bug type based on the limited
276 information it has. The actual type of the bug might be different.
277
278 Generic KASAN also reports up to two auxiliary call stack traces. These stack
279 traces point to places in code that interacted with the object but that are not
280 directly present in the bad access stack trace. Currently, this includes
281 call_rcu() and workqueue queuing.
282
283 CONFIG_KASAN_EXTRA_INFO
284 ~~~~~~~~~~~~~~~~~~~~~~~
285
286 Enabling CONFIG_KASAN_EXTRA_INFO allows KASAN to record and report more
287 information. The extra information currently supported is the CPU number and
288 timestamp at allocation and free. More information can help find the cause of
289 the bug and correlate the error with other system events, at the cost of using
290 extra memory to record more information (more cost details in the help text of
291 CONFIG_KASAN_EXTRA_INFO).
292
293 Here is the report with CONFIG_KASAN_EXTRA_INFO enabled (only the
294 different parts are shown)::
295
296 ==================================================================
297 ...
298 Allocated by task 134 on cpu 5 at 229.133855s:
299 ...
300 Freed by task 136 on cpu 3 at 230.199335s:
301 ...
302 ==================================================================
303
304 Implementation details
305 ----------------------
306
307 Generic KASAN
308 ~~~~~~~~~~~~~
309
310 Software KASAN modes use shadow memory to record whether each byte of memory is
311 safe to access and use compile-time instrumentation to insert shadow memory
312 checks before each memory access.
313
314 Generic KASAN dedicates 1/8th of kernel memory to its shadow memory (16TB
315 to cover 128TB on x86_64) and uses direct mapping with a scale and offset to
316 translate a memory address to its corresponding shadow address.
317
318 Here is the function which translates an address to its corresponding shadow
319 address::
320
321 static inline void *kasan_mem_to_shadow(const void *addr)
322 {
323 return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
324 + KASAN_SHADOW_OFFSET;
325 }
326
327 where ``KASAN_SHADOW_SCALE_SHIFT = 3``.
328
329 Compile-time instrumentation is used to insert memory access checks. Compiler
330 inserts function calls (``__asan_load*(addr)``, ``__asan_store*(addr)``) before
331 each memory access of size 1, 2, 4, 8, or 16. These functions check whether
332 memory accesses are valid or not by checking corresponding shadow memory.
333
334 With inline instrumentation, instead of making function calls, the compiler
335 directly inserts the code to check shadow memory. This option significantly
336 enlarges the kernel, but it gives an x1.1-x2 performance boost over the
337 outline-instrumented kernel.
338
339 Generic KASAN is the only mode that delays the reuse of freed objects via
340 quarantine (see mm/kasan/quarantine.c for implementation).
341
342 Software Tag-Based KASAN
343 ~~~~~~~~~~~~~~~~~~~~~~~~
344
345 Software Tag-Based KASAN uses a software memory tagging approach to checking
346 access validity. It is currently only implemented for the arm64 architecture.
347
348 Software Tag-Based KASAN uses the Top Byte Ignore (TBI) feature of arm64 CPUs
349 to store a pointer tag in the top byte of kernel pointers. It uses shadow memory
350 to store memory tags associated with each 16-byte memory cell (therefore, it
351 dedicates 1/16th of the kernel memory for shadow memory).
352
353 On each memory allocation, Software Tag-Based KASAN generates a random tag, tags
354 the allocated memory with this tag, and embeds the same tag into the returned
355 pointer.
356
357 Software Tag-Based KASAN uses compile-time instrumentation to insert checks
358 before each memory access. These checks make sure that the tag of the memory
359 that is being accessed is equal to the tag of the pointer that is used to access
360 this memory. In case of a tag mismatch, Software Tag-Based KASAN prints a bug
361 report.
362
363 Software Tag-Based KASAN also has two instrumentation modes (outline, which
364 emits callbacks to check memory accesses; and inline, which performs the shadow
365 memory checks inline). With outline instrumentation mode, a bug report is
366 printed from the function that performs the access check. With inline
367 instrumentation, a ``brk`` instruction is emitted by the compiler, and a
368 dedicated ``brk`` handler is used to print bug reports.
369
370 Software Tag-Based KASAN uses 0xFF as a match-all pointer tag (accesses through
371 pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
372 reserved to tag freed memory regions.
373
374 Hardware Tag-Based KASAN
375 ~~~~~~~~~~~~~~~~~~~~~~~~
376
377 Hardware Tag-Based KASAN is similar to the software mode in concept but uses
378 hardware memory tagging support instead of compiler instrumentation and
379 shadow memory.
380
381 Hardware Tag-Based KASAN is currently only implemented for arm64 architecture
382 and based on both arm64 Memory Tagging Extension (MTE) introduced in ARMv8.5
383 Instruction Set Architecture and Top Byte Ignore (TBI).
384
385 Special arm64 instructions are used to assign memory tags for each allocation.
386 Same tags are assigned to pointers to those allocations. On every memory
387 access, hardware makes sure that the tag of the memory that is being accessed is
388 equal to the tag of the pointer that is used to access this memory. In case of a
389 tag mismatch, a fault is generated, and a report is printed.
390
391 Hardware Tag-Based KASAN uses 0xFF as a match-all pointer tag (accesses through
392 pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
393 reserved to tag freed memory regions.
394
395 If the hardware does not support MTE (pre ARMv8.5), Hardware Tag-Based KASAN
396 will not be enabled. In this case, all KASAN boot parameters are ignored.
397
398 Note that enabling CONFIG_KASAN_HW_TAGS always results in in-kernel TBI being
399 enabled. Even when ``kasan.mode=off`` is provided or when the hardware does not
400 support MTE (but supports TBI).
401
402 Hardware Tag-Based KASAN only reports the first found bug. After that, MTE tag
403 checking gets disabled.
404
405 Shadow memory
406 -------------
407
408 The contents of this section are only applicable to software KASAN modes.
409
410 The kernel maps memory in several different parts of the address space.
411 The range of kernel virtual addresses is large: there is not enough real
412 memory to support a real shadow region for every address that could be
413 accessed by the kernel. Therefore, KASAN only maps real shadow for certain
414 parts of the address space.
415
416 Default behaviour
417 ~~~~~~~~~~~~~~~~~
418
419 By default, architectures only map real memory over the shadow region
420 for the linear mapping (and potentially other small areas). For all
421 other areas - such as vmalloc and vmemmap space - a single read-only
422 page is mapped over the shadow area. This read-only shadow page
423 declares all memory accesses as permitted.
424
425 This presents a problem for modules: they do not live in the linear
426 mapping but in a dedicated module space. By hooking into the module
427 allocator, KASAN temporarily maps real shadow memory to cover them.
428 This allows detection of invalid accesses to module globals, for example.
429
430 This also creates an incompatibility with ``VMAP_STACK``: if the stack
431 lives in vmalloc space, it will be shadowed by the read-only page, and
432 the kernel will fault when trying to set up the shadow data for stack
433 variables.
434
435 CONFIG_KASAN_VMALLOC
436 ~~~~~~~~~~~~~~~~~~~~
437
438 With ``CONFIG_KASAN_VMALLOC``, KASAN can cover vmalloc space at the
439 cost of greater memory usage. Currently, this is supported on x86,
440 arm64, riscv, s390, and powerpc.
441
442 This works by hooking into vmalloc and vmap and dynamically
443 allocating real shadow memory to back the mappings.
444
445 Most mappings in vmalloc space are small, requiring less than a full
446 page of shadow space. Allocating a full shadow page per mapping would
447 therefore be wasteful. Furthermore, to ensure that different mappings
448 use different shadow pages, mappings would have to be aligned to
449 ``KASAN_GRANULE_SIZE * PAGE_SIZE``.
450
451 Instead, KASAN shares backing space across multiple mappings. It allocates
452 a backing page when a mapping in vmalloc space uses a particular page
453 of the shadow region. This page can be shared by other vmalloc
454 mappings later on.
455
456 KASAN hooks into the vmap infrastructure to lazily clean up unused shadow
457 memory.
458
459 To avoid the difficulties around swapping mappings around, KASAN expects
460 that the part of the shadow region that covers the vmalloc space will
461 not be covered by the early shadow page but will be left unmapped.
462 This will require changes in arch-specific code.
463
464 This allows ``VMAP_STACK`` support on x86 and can simplify support of
465 architectures that do not have a fixed module region.
466
467 For developers
468 --------------
469
470 Ignoring accesses
471 ~~~~~~~~~~~~~~~~~
472
473 Software KASAN modes use compiler instrumentation to insert validity checks.
474 Such instrumentation might be incompatible with some parts of the kernel, and
475 therefore needs to be disabled.
476
477 Other parts of the kernel might access metadata for allocated objects.
478 Normally, KASAN detects and reports such accesses, but in some cases (e.g.,
479 in memory allocators), these accesses are valid.
480
481 For software KASAN modes, to disable instrumentation for a specific file or
482 directory, add a ``KASAN_SANITIZE`` annotation to the respective kernel
483 Makefile:
484
485 - For a single file (e.g., main.o)::
486
487 KASAN_SANITIZE_main.o := n
488
489 - For all files in one directory::
490
491 KASAN_SANITIZE := n
492
493 For software KASAN modes, to disable instrumentation on a per-function basis,
494 use the KASAN-specific ``__no_sanitize_address`` function attribute or the
495 generic ``noinstr`` one.
496
497 Note that disabling compiler instrumentation (either on a per-file or a
498 per-function basis) makes KASAN ignore the accesses that happen directly in
499 that code for software KASAN modes. It does not help when the accesses happen
500 indirectly (through calls to instrumented functions) or with Hardware
501 Tag-Based KASAN, which does not use compiler instrumentation.
502
503 For software KASAN modes, to disable KASAN reports in a part of the kernel code
504 for the current task, annotate this part of the code with a
505 ``kasan_disable_current()``/``kasan_enable_current()`` section. This also
506 disables the reports for indirect accesses that happen through function calls.
507
508 For tag-based KASAN modes, to disable access checking, use
509 ``kasan_reset_tag()`` or ``page_kasan_tag_reset()``. Note that temporarily
510 disabling access checking via ``page_kasan_tag_reset()`` requires saving and
511 restoring the per-page KASAN tag via ``page_kasan_tag``/``page_kasan_tag_set``.
512
513 Tests
514 ~~~~~
515
516 There are KASAN tests that allow verifying that KASAN works and can detect
517 certain types of memory corruptions.
518
519 All KASAN tests are integrated with the KUnit Test Framework and can be enabled
520 via ``CONFIG_KASAN_KUNIT_TEST``. The tests can be run and partially verified
521 automatically in a few different ways; see the instructions below.
522
523 Each KASAN test prints one of multiple KASAN reports if an error is detected.
524 Then the test prints its number and status.
525
526 When a test passes::
527
528 ok 28 - kmalloc_double_kzfree
529
530 When a test fails due to a failed ``kmalloc``::
531
532 # kmalloc_large_oob_right: ASSERTION FAILED at mm/kasan/kasan_test.c:245
533 Expected ptr is not null, but is
534 not ok 5 - kmalloc_large_oob_right
535
536 When a test fails due to a missing KASAN report::
537
538 # kmalloc_double_kzfree: EXPECTATION FAILED at mm/kasan/kasan_test.c:709
539 KASAN failure expected in "kfree_sensitive(ptr)", but none occurred
540 not ok 28 - kmalloc_double_kzfree
541
542
543 At the end the cumulative status of all KASAN tests is printed. On success::
544
545 ok 1 - kasan
546
547 Or, if one of the tests failed::
548
549 not ok 1 - kasan
550
551 There are a few ways to run the KASAN tests.
552
553 1. Loadable module
554
555 With ``CONFIG_KUNIT`` enabled, the tests can be built as a loadable module
556 and run by loading ``kasan_test.ko`` with ``insmod`` or ``modprobe``.
557
558 2. Built-In
559
560 With ``CONFIG_KUNIT`` built-in, the tests can be built-in as well.
561 In this case, the tests will run at boot as a late-init call.
562
563 3. Using kunit_tool
564
565 With ``CONFIG_KUNIT`` and ``CONFIG_KASAN_KUNIT_TEST`` built-in, it is also
566 possible to use ``kunit_tool`` to see the results of KUnit tests in a more
567 readable way. This will not print the KASAN reports of the tests that passed.
568 See `KUnit documentation <https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html>`_
569 for more up-to-date information on ``kunit_tool``.
570
571 .. _KUnit: https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html
572

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

KASAN 개요와 세 가지 mode

1-40

SPDX 라이선스 식별자: GPL-2.0

저작권 (C) 2023, Google LLC.

Kernel Address Sanitizer (KASAN)

개요

Kernel Address Sanitizer(KASAN)는 out-of-bounds와 use-after-free bug를 찾도록 설계된 동적 memory safety error detector입니다.

KASAN에는 Generic KASAN, Software Tag-Based KASAN, Hardware Tag-Based KASAN의 세 가지 mode가 있습니다.

CONFIG_KASAN_GENERIC으로 활성화하는 Generic KASAN은 userspace ASan과 비슷한 debugging용 mode입니다. 여러 CPU architecture에서 지원하지만 performance와 memory overhead가 큽니다.

CONFIG_KASAN_SW_TAGS로 활성화하는 Software Tag-Based KASAN, 즉 SW_TAGS KASAN은 userspace HWASan과 비슷하게 debugging과 dogfood testing에 모두 사용할 수 있습니다. arm64에서만 지원하지만 memory overhead가 중간 수준이므로 memory가 제한된 device에서 실제 workload를 이용한 testing에 사용할 수 있습니다.

CONFIG_KASAN_HW_TAGS로 활성화하는 Hardware Tag-Based KASAN, 즉 HW_TAGS KASAN은 현장 memory bug detector 또는 security mitigation으로 사용하기 위한 mode입니다. MTE(Memory Tagging Extension)를 지원하는 arm64 CPU에서만 동작하지만 memory와 performance overhead가 낮아 production에서 사용할 수 있습니다.

각 KASAN mode의 memory 및 performance 영향에 관한 자세한 내용은 해당 Kconfig option 설명을 참조하십시오.

Generic과 Software Tag-Based mode를 보통 software mode라고 부릅니다. Software Tag-Based와 Hardware Tag-Based mode는 tag-based mode라고 부릅니다.

지원 architecture, compiler, memory 유형

41-80

지원

Architecture

Generic KASAN은 x86_64, arm, arm64, powerpc, riscv, s390, xtensa, loongarch에서 지원하며 tag-based KASAN mode는 arm64에서만 지원합니다.

Compiler

software KASAN mode는 모든 memory access 앞에 validity check를 삽입하는 compile-time instrumentation을 사용하므로 이를 지원하는 compiler version이 필요합니다. Hardware Tag-Based mode는 hardware가 검사를 수행하지만 memory tagging instruction을 지원하는 compiler version이 여전히 필요합니다.

Generic KASAN에는 GCC 8.3.0 이상 또는 커널이 지원하는 어떤 Clang version이든 사용할 수 있습니다.

Software Tag-Based KASAN에는 GCC 11 이상 또는 커널이 지원하는 어떤 Clang version이든 사용할 수 있습니다.

Hardware Tag-Based KASAN에는 GCC 10 이상 또는 Clang 12 이상이 필요합니다.

Memory 유형

Generic KASAN은 slab, page_alloc, vmap, vmalloc, stack, global memory의 bug를 찾을 수 있습니다.

Software Tag-Based KASAN은 slab, page_alloc, vmalloc, stack memory를 지원합니다.

Hardware Tag-Based KASAN은 slab, page_alloc, non-executable vmalloc memory를 지원합니다.

slab의 경우 두 software KASAN mode 모두 SLUB와 SLAB allocator를 지원하지만 Hardware Tag-Based KASAN은 SLUB만 지원합니다.

KASAN 구성과 stack trace

81-99

사용법

KASAN을 활성화하려면 커널을 다음과 같이 구성하십시오.

CONFIG_KASAN=y

그리고 Generic KASAN을 위한 `CONFIG_KASAN_GENERIC`, Software Tag-Based KASAN을 위한 `CONFIG_KASAN_SW_TAGS`, Hardware Tag-Based KASAN을 위한 `CONFIG_KASAN_HW_TAGS` 가운데 하나를 선택하십시오.

software mode에서는 `CONFIG_KASAN_OUTLINE`과 `CONFIG_KASAN_INLINE` 중 하나도 선택하십시오. outline과 inline은 compiler instrumentation 유형입니다. 전자는 더 작은 binary를 만들고 후자는 최대 2배 빠릅니다.

영향을 받은 slab object의 alloc 및 free stack trace를 report에 포함하려면 `CONFIG_STACKTRACE`를 활성화하십시오. 영향을 받은 physical page의 alloc 및 free stack trace를 포함하려면 `CONFIG_PAGE_OWNER`를 활성화하고 `page_owner=on`으로 boot하십시오.

boot parameter와 hardware tag 검사 정책

100-168

Boot parameter

KASAN은 공통 `panic_on_warn` command line parameter의 영향을 받습니다. 이를 활성화하면 KASAN이 bug report를 출력한 뒤 kernel panic을 일으킵니다.

기본적으로 KASAN은 첫 번째 invalid memory access에 대해서만 bug report를 출력합니다. `kasan_multi_shot`을 사용하면 invalid access마다 report를 출력합니다. 이는 KASAN report에 대해 `panic_on_warn`을 사실상 비활성화합니다.

또는 `panic_on_warn`과 독립적으로 `kasan.fault=` boot parameter로 panic과 reporting 동작을 제어할 수 있습니다.

`kasan.fault=report`, `=panic`, `=panic_on_write`는 KASAN report만 출력할지, kernel panic을 일으킬지, invalid write에서만 panic을 일으킬지 제어합니다. 기본값은 `report`입니다. `kasan_multi_shot`이 활성화되어도 panic은 발생합니다. Hardware Tag-Based KASAN의 asynchronous mode에서는 `kasan.fault=panic_on_write`가 read를 포함해 비동기적으로 검사한 access에서 항상 panic을 일으킵니다.

Software 및 Hardware Tag-Based KASAN mode는 stack trace 수집 동작 변경을 지원합니다.

`kasan.stacktrace=off` 또는 `=on`은 alloc 및 free stack trace 수집을 비활성화하거나 활성화합니다. 기본값은 `on`입니다.

`kasan.stack_ring_size=<number of entries>`는 stack ring의 entry 수를 지정합니다. 기본값은 `32768`입니다.

Hardware Tag-Based KASAN은 production에서 security mitigation으로 사용하기 위한 mode이므로 KASAN 전체를 비활성화하거나 기능을 제어하는 추가 boot parameter를 지원합니다.

`kasan=off` 또는 `=on`은 KASAN 활성화 여부를 제어합니다. 기본값은 `on`입니다.

`kasan.mode=sync`, `=async`, `=asymm`은 KASAN을 synchronous, asynchronous, asymmetric 실행 mode 중 무엇으로 구성할지 제어합니다. 기본값은 `sync`입니다.

synchronous mode에서는 tag check fault가 발생할 때 bad access를 즉시 감지합니다. asynchronous mode에서는 감지가 지연됩니다. tag check fault가 발생하면 정보를 hardware, arm64의 경우 TFSR_EL1 register에 저장하고 kernel이 hardware를 주기적으로 검사할 때만 tag fault를 보고합니다. asymmetric mode에서는 read의 bad access를 동기적으로, write의 bad access를 비동기적으로 감지합니다.

`kasan.write_only=off` 또는 `kasan.write_only=on`은 write(store) access만 검사할지 모든 access를 검사할지 제어합니다. 기본값은 `off`입니다.

`kasan.vmalloc=off` 또는 `=on`은 vmalloc allocation tagging을 비활성화하거나 활성화합니다. 기본값은 `on`입니다.

`kasan.page_alloc.sample=<sampling interval>`은 order가 `kasan.page_alloc.sample.order` 이상인 page_alloc allocation 중 N번째마다 KASAN tag를 지정합니다. N은 `sample` 값이며 기본값은 `1`, 즉 해당하는 모든 allocation을 tag하는 것입니다. 이 parameter는 KASAN의 performance overhead를 줄이기 위한 것입니다.

이 parameter를 활성화하면 Hardware Tag-Based KASAN이 sampling에서 선택되지 않은 allocation의 검사를 건너뛰므로 해당 allocation의 bad access를 놓칠 수 있습니다. 정확한 bug 탐지를 위해서는 기본값을 사용하십시오.

`kasan.page_alloc.sample.order=<minimum page order>`는 sampling의 영향을 받는 allocation의 최소 order를 지정합니다. 기본값은 `3`입니다. `kasan.page_alloc.sample`이 `1`보다 클 때만 적용됩니다. performance overhead의 가장 큰 원인인 큰 page_alloc allocation만 sampling할 수 있게 하기 위한 parameter입니다.

KASAN error report 해석

169-282

Error report

일반적인 KASAN report는 다음과 같습니다.

==================================================================
BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0xa8/0xbc [kasan_test]
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 [kasan_test]
 kmalloc_tests_init+0x16/0x700 [kasan_test]
 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 [kasan_test]
 kmalloc_tests_init+0x16/0x700 [kasan_test]
 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
==================================================================
KASAN report 구성
영역핵심 정보
Headerbug type, access 종류와 크기, fault address, task
Bad access stackinvalid access가 발생한 호출 경로
Allocation stack접근한 object가 할당된 호출 경로
Free stackuse-after-free인 경우 object가 해제된 호출 경로
Object와 pageslab cache, object 범위, page metadata
Memory statefault address 주변 shadow byte와 접근 가능 상태

긴 diagnostic 출력의 각 영역이 제공하는 조사 단서를 구조화했습니다.

report header는 발생한 bug 종류와 이를 일으킨 access 종류를 요약합니다. 이어서 bad access의 stack trace, 접근한 memory가 할당된 위치의 stack trace(slab object에 접근한 경우), object를 해제한 위치의 stack trace(use-after-free report인 경우)가 나옵니다. 다음에는 접근한 slab object 설명과 접근한 memory page 정보가 나옵니다.

마지막에는 접근한 address 주변의 memory state를 보여 줍니다. 내부적으로 KASAN은 KASAN mode에 따라 8 또는 16 aligned byte인 각 memory granule의 상태를 따로 추적합니다. report의 memory state 절에 있는 각 숫자는 접근한 address 주변 granule 하나의 상태를 나타냅니다.

Generic KASAN의 memory granule 크기는 8이며 각 granule 상태는 shadow byte 하나로 encode됩니다. 8byte는 accessible, partially accessible, freed 또는 redzone 일부일 수 있습니다. shadow byte `00`은 해당 8byte 모두 접근 가능함을 뜻합니다. N(1 <= N <= 7)은 처음 Nbyte가 접근 가능하고 나머지 (8 - N)byte는 접근할 수 없음을 뜻합니다. 음수 값은 8byte word 전체에 접근할 수 없음을 나타냅니다. KASAN은 redzone이나 freed memory 같은 접근 불가 유형을 구분하려고 서로 다른 음수 값을 사용합니다. `mm/kasan/kasan.h`를 참조하십시오.

위 report에서 화살표는 shadow byte `03`을 가리키며, 이는 접근한 address가 부분적으로만 접근 가능함을 뜻합니다.

tag-based KASAN mode에서는 report의 마지막 절이 접근한 address 주변의 memory tag를 보여 줍니다. '구현 세부 사항' 절을 참조하십시오.

`slab-out-of-bounds`나 `use-after-free` 같은 KASAN bug title은 best-effort 결과입니다. KASAN은 제한된 정보를 바탕으로 가장 가능성 높은 bug type을 출력하며 실제 bug type은 다를 수 있습니다.

Generic KASAN은 최대 두 개의 auxiliary call stack trace도 보고합니다. 이 trace는 object와 상호작용했지만 bad access stack trace에는 직접 나타나지 않는 코드 위치를 가리킵니다. 현재는 `call_rcu()`와 workqueue queuing이 포함됩니다.

CONFIG_KASAN_EXTRA_INFO

283-303

CONFIG_KASAN_EXTRA_INFO

CONFIG_KASAN_EXTRA_INFO를 활성화하면 KASAN이 더 많은 정보를 기록하고 보고할 수 있습니다. 현재 지원하는 추가 정보는 allocation 및 free 시점의 CPU 번호와 timestamp입니다. 추가 정보는 더 많은 정보를 기록하기 위한 memory 비용을 대가로 bug 원인을 찾고 error를 다른 system event와 연관시키는 데 도움을 줍니다. 비용에 관한 자세한 내용은 CONFIG_KASAN_EXTRA_INFO help text에 있습니다.

CONFIG_KASAN_EXTRA_INFO를 활성화한 report는 다음과 같습니다. 달라지는 부분만 표시합니다.

==================================================================
...
Allocated by task 134 on cpu 5 at 229.133855s:
...
Freed by task 136 on cpu 3 at 230.199335s:
...
==================================================================

Generic KASAN 구현

304-341

구현 세부 사항

Generic KASAN

software KASAN mode는 각 memory byte에 안전하게 접근할 수 있는지를 shadow memory에 기록하고 compile-time instrumentation으로 각 memory access 앞에 shadow memory check를 삽입합니다.

Generic KASAN은 kernel memory의 1/8을 shadow memory에 할당합니다. x86_64에서는 128TB를 다루기 위해 16TB를 사용하며, scale과 offset을 이용한 direct mapping으로 memory address를 해당 shadow address로 변환합니다.

address를 해당 shadow address로 변환하는 함수는 다음과 같습니다.

static inline void *kasan_mem_to_shadow(const void *addr)
{
    return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
            + KASAN_SHADOW_OFFSET;
}

여기서 `KASAN_SHADOW_SCALE_SHIFT = 3`입니다.

compile-time instrumentation이 memory access check를 삽입합니다. compiler는 크기 1, 2, 4, 8, 16의 각 memory access 앞에 `__asan_load*(addr)` 또는 `__asan_store*(addr)` 함수 호출을 삽입합니다. 이 함수들은 해당 shadow memory를 검사해 memory access가 유효한지 확인합니다.

inline instrumentation에서는 함수 호출 대신 compiler가 shadow memory 검사 코드를 직접 삽입합니다. 이 옵션은 kernel을 상당히 크게 만들지만 outline instrumentation kernel보다 1.1배에서 2배 빠릅니다.

Generic KASAN은 quarantine을 통해 freed object의 재사용을 지연하는 유일한 mode입니다. 구현은 `mm/kasan/quarantine.c`를 참조하십시오.

Software Tag-Based KASAN 구현

342-373

Software Tag-Based KASAN

Software Tag-Based KASAN은 software memory tagging 방식으로 access validity를 검사합니다. 현재 arm64 architecture에만 구현되어 있습니다.

arm64 CPU의 Top Byte Ignore(TBI) 기능을 사용해 kernel pointer의 top byte에 pointer tag를 저장합니다. shadow memory에는 각 16byte memory cell과 연관된 memory tag를 저장하므로 kernel memory의 1/16을 shadow memory에 할당합니다.

각 memory allocation에서 random tag를 생성해 할당한 memory에 지정하고 반환하는 pointer에도 같은 tag를 넣습니다.

compile-time instrumentation으로 각 memory access 앞에 검사를 삽입합니다. 접근하는 memory의 tag와 그 memory에 접근할 때 사용하는 pointer의 tag가 같은지 확인하며, tag가 일치하지 않으면 bug report를 출력합니다.

Software Tag-Based KASAN에도 outline과 inline의 두 instrumentation mode가 있습니다. outline은 memory access를 검사하는 callback을 내보내며 report는 access check 함수에서 출력됩니다. inline은 shadow memory check를 inline으로 수행하고 compiler가 `brk` instruction을 내보내며 전용 `brk` handler가 bug report를 출력합니다.

pointer tag 0xFF는 모든 tag와 일치하는 match-all tag로 사용하므로 0xFF tag pointer를 통한 access는 검사하지 않습니다. 0xFE는 freed memory region에 tag를 지정하기 위해 예약되어 있습니다.

Hardware Tag-Based KASAN 구현

374-404

Hardware Tag-Based KASAN

개념적으로 software mode와 비슷하지만 compiler instrumentation과 shadow memory 대신 hardware memory tagging 지원을 사용합니다.

현재 arm64 architecture에만 구현되어 있으며 ARMv8.5 Instruction Set Architecture에서 도입한 arm64 Memory Tagging Extension(MTE)과 Top Byte Ignore(TBI)를 모두 기반으로 합니다.

특수 arm64 instruction으로 각 allocation에 memory tag를 지정하고 해당 allocation의 pointer에도 같은 tag를 지정합니다. 매 memory access에서 hardware가 memory tag와 pointer tag가 같은지 확인합니다. tag가 다르면 fault가 발생하고 report가 출력됩니다.

0xFF를 match-all pointer tag로 사용해 이 tag를 가진 pointer access는 검사하지 않습니다. 0xFE는 freed memory region tagging에 예약되어 있습니다.

hardware가 MTE를 지원하지 않는 ARMv8.5 이전 환경에서는 Hardware Tag-Based KASAN이 활성화되지 않으며 모든 KASAN boot parameter를 무시합니다.

CONFIG_KASAN_HW_TAGS를 활성화하면 항상 in-kernel TBI도 활성화됩니다. `kasan.mode=off`를 지정했거나 hardware가 MTE는 지원하지 않고 TBI만 지원해도 마찬가지입니다.

Hardware Tag-Based KASAN은 처음 발견한 bug만 보고하며 이후에는 MTE tag checking을 비활성화합니다.

shadow memory와 CONFIG_KASAN_VMALLOC

405-466

Shadow memory

이 절의 내용은 software KASAN mode에만 적용됩니다.

kernel은 address space의 여러 영역에 memory를 mapping합니다. kernel virtual address 범위가 매우 커서 kernel이 접근할 수 있는 모든 address마다 실제 shadow region을 지원할 real memory가 충분하지 않습니다. 따라서 KASAN은 address space의 특정 영역에만 실제 shadow를 mapping합니다.

기본 동작

기본적으로 architecture는 linear mapping과 일부 작은 영역의 shadow region에만 real memory를 mapping합니다. vmalloc 및 vmemmap space 같은 다른 모든 영역에는 shadow area 전체에 하나의 read-only page를 mapping하며, 이 page는 모든 memory access를 허용된 것으로 선언합니다.

module은 linear mapping이 아니라 전용 module space에 있으므로 문제가 됩니다. KASAN은 module allocator에 hook을 걸어 module을 다루는 동안 real shadow memory를 임시로 mapping합니다. 이를 통해 module global에 대한 invalid access 등을 탐지할 수 있습니다.

이 방식은 `VMAP_STACK`과도 호환되지 않습니다. stack이 vmalloc space에 있으면 read-only page가 shadow를 제공하므로 kernel이 stack variable의 shadow data를 설정하려 할 때 fault가 발생합니다.

CONFIG_KASAN_VMALLOC

`CONFIG_KASAN_VMALLOC`을 사용하면 memory 사용량 증가를 대가로 KASAN이 vmalloc space를 다룰 수 있습니다. 현재 x86, arm64, riscv, s390, powerpc에서 지원합니다.

vmalloc과 vmap에 hook을 걸고 mapping을 뒷받침하는 real shadow memory를 동적으로 할당하는 방식으로 동작합니다.

vmalloc space의 대부분 mapping은 작아서 shadow space 한 page보다 적게 필요합니다. mapping마다 shadow page 전체를 할당하면 낭비이며, 서로 다른 mapping이 서로 다른 shadow page를 사용하도록 보장하려면 mapping을 `KASAN_GRANULE_SIZE * PAGE_SIZE`에 align해야 합니다.

대신 KASAN은 여러 mapping이 backing space를 공유하게 합니다. vmalloc space의 mapping이 shadow region의 특정 page를 사용할 때 backing page를 할당하고, 이후 다른 vmalloc mapping이 이 page를 공유할 수 있습니다.

KASAN은 vmap infrastructure에 hook을 걸어 사용하지 않는 shadow memory를 lazy cleanup합니다.

mapping을 교체할 때 생기는 어려움을 피하기 위해 KASAN은 vmalloc space를 다루는 shadow region 부분을 early shadow page가 덮지 않고 unmapped 상태로 남겨 두기를 기대합니다. 이를 위해 arch-specific code 변경이 필요합니다.

이 방식은 x86에서 `VMAP_STACK` 지원을 가능하게 하고 고정 module region이 없는 architecture 지원을 단순화할 수 있습니다.

개발자를 위한 access 검사 제외

467-512

개발자를 위한 정보

Access 무시

software KASAN mode는 compiler instrumentation으로 validity check를 삽입합니다. 이런 instrumentation은 kernel 일부와 호환되지 않을 수 있으므로 비활성화해야 할 수 있습니다.

kernel의 다른 부분은 할당된 object의 metadata에 접근할 수 있습니다. 일반적으로 KASAN은 이를 탐지해 보고하지만 memory allocator 같은 일부 경우에는 유효한 access입니다.

software KASAN mode에서 특정 파일이나 directory의 instrumentation을 비활성화하려면 해당 kernel Makefile에 `KASAN_SANITIZE` annotation을 추가하십시오.

단일 파일, 예를 들어 main.o에는 다음을 사용합니다.

KASAN_SANITIZE_main.o := n

한 directory의 모든 파일에는 다음을 사용합니다.

KASAN_SANITIZE := n

software KASAN mode에서 함수별로 instrumentation을 비활성화하려면 KASAN 전용 `__no_sanitize_address` function attribute 또는 공통 `noinstr`를 사용하십시오.

file 또는 function 단위로 compiler instrumentation을 비활성화하면 software KASAN mode가 해당 코드에서 직접 발생하는 access를 무시합니다. instrumented function 호출을 통한 간접 access나 compiler instrumentation을 사용하지 않는 Hardware Tag-Based KASAN에는 도움이 되지 않습니다.

현재 task의 kernel code 일부에서 KASAN report를 비활성화하려면 그 코드를 `kasan_disable_current()`와 `kasan_enable_current()` 구간으로 표시하십시오. function call을 통해 발생하는 간접 access report도 비활성화합니다.

tag-based KASAN mode에서 access checking을 비활성화하려면 `kasan_reset_tag()` 또는 `page_kasan_tag_reset()`을 사용하십시오. `page_kasan_tag_reset()`으로 일시적으로 검사를 비활성화할 때는 `page_kasan_tag`와 `page_kasan_tag_set`으로 page별 KASAN tag를 저장하고 복원해야 합니다.

KASAN KUnit test 실행과 결과

513-571

Test

KASAN이 동작하고 특정 유형의 memory corruption을 탐지할 수 있는지 검증하는 KASAN test가 있습니다.

모든 KASAN test는 KUnit Test Framework와 통합되어 있으며 `CONFIG_KASAN_KUNIT_TEST`로 활성화할 수 있습니다. 아래 설명처럼 몇 가지 방법으로 test를 실행하고 부분적으로 자동 검증할 수 있습니다.

각 KASAN test는 error가 감지되면 여러 KASAN report 중 하나를 출력한 뒤 test 번호와 status를 출력합니다.

test가 통과하면 다음과 같이 출력합니다.

ok 28 - kmalloc_double_kzfree

`kmalloc` 실패로 test가 실패하면 다음과 같습니다.

# kmalloc_large_oob_right: ASSERTION FAILED at mm/kasan/kasan_test.c:245
Expected ptr is not null, but is
not ok 5 - kmalloc_large_oob_right

필요한 KASAN report가 없어 test가 실패하면 다음과 같습니다.

# kmalloc_double_kzfree: EXPECTATION FAILED at mm/kasan/kasan_test.c:709
KASAN failure expected in "kfree_sensitive(ptr)", but none occurred
not ok 28 - kmalloc_double_kzfree

마지막에는 모든 KASAN test의 누적 status를 출력합니다. 성공한 경우는 다음과 같습니다.

ok 1 - kasan

test 중 하나가 실패한 경우는 다음과 같습니다.

not ok 1 - kasan

KASAN test를 실행하는 방법은 몇 가지가 있습니다.

1. loadable module: `CONFIG_KUNIT`이 활성화되어 있으면 test를 loadable module로 build하고 `insmod` 또는 `modprobe`로 `kasan_test.ko`를 load해 실행할 수 있습니다.

2. built-in: `CONFIG_KUNIT`이 built-in이면 test도 built-in으로 만들 수 있습니다. 이 경우 boot 중 late-init call로 실행됩니다.

3. kunit_tool 사용: `CONFIG_KUNIT`과 `CONFIG_KASAN_KUNIT_TEST`가 built-in이면 `kunit_tool`로 KUnit test 결과를 더 읽기 쉽게 볼 수 있습니다. 통과한 test의 KASAN report는 출력하지 않습니다. 최신 `kunit_tool` 정보는 `KUnit documentation <https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html>`을 참조하십시오.

KUnit: https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html