~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/translations/zh_CN/dev-tools/kasan.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/translations/zh_CN/dev-tools/kasan.rst (Version linux-6.12-rc7) and /Documentation/translations/zh_CN/dev-tools/kasan.rst (Version linux-6.8.12)


  1 .. SPDX-License-Identifier: GPL-2.0                 1 .. SPDX-License-Identifier: GPL-2.0
  2                                                     2 
  3 .. include:: ../disclaimer-zh_CN.rst                3 .. include:: ../disclaimer-zh_CN.rst
  4                                                     4 
  5 :Original: Documentation/dev-tools/kasan.rst        5 :Original: Documentation/dev-tools/kasan.rst
  6 :Translator: 万家兵 Wan Jiabing <wanjiabing@      6 :Translator: 万家兵 Wan Jiabing <wanjiabing@vivo.com>
  7                                                     7 
  8 内核地址消毒剂(KASAN)                        8 内核地址消毒剂(KASAN)
  9 =====================                               9 =====================
 10                                                    10 
 11 概述                                             11 概述
 12 ----                                               12 ----
 13                                                    13 
 14 Kernel Address SANitizer(KASAN)是一种动态     14 Kernel Address SANitizer(KASAN)是一种动态内存安全错误检测工具,主要功能是
 15 检查内存越界访问和使用已释放内     15 检查内存越界访问和使用已释放内存的问题。
 16                                                    16 
 17 KASAN有三种模式:                              17 KASAN有三种模式:
 18                                                    18 
 19 1. 通用KASAN                                     19 1. 通用KASAN
 20 2. 基于软件标签的KASAN                      20 2. 基于软件标签的KASAN
 21 3. 基于硬件标签的KASAN                      21 3. 基于硬件标签的KASAN
 22                                                    22 
 23 用CONFIG_KASAN_GENERIC启用的通用KASAN,     23 用CONFIG_KASAN_GENERIC启用的通用KASAN,是用于调试的模式,类似于用户空
 24 间的ASan。这种模式在许多CPU架构上     24 间的ASan。这种模式在许多CPU架构上都被支持,但它有明显的性能和内存开销。
 25                                                    25 
 26 基于软件标签的KASAN或SW_TAGS KASAN,     26 基于软件标签的KASAN或SW_TAGS KASAN,通过CONFIG_KASAN_SW_TAGS启用,
 27 可以用于调试和自我测试,类似于     27 可以用于调试和自我测试,类似于用户空间HWASan。这种模式只支持arm64,但其
 28 适度的内存开销允许在内存受限的     28 适度的内存开销允许在内存受限的设备上用真实的工作负载进行测试。
 29                                                    29 
 30 基于硬件标签的KASAN或HW_TAGS KASAN,     30 基于硬件标签的KASAN或HW_TAGS KASAN,用CONFIG_KASAN_HW_TAGS启用,被
 31 用作现场内存错误检测器或作为安     31 用作现场内存错误检测器或作为安全缓解的模式。这种模式只在支持MTE(内存标签
 32 扩展)的arm64 CPU上工作,但它的内     32 扩展)的arm64 CPU上工作,但它的内存和性能开销很低,因此可以在生产中使用。
 33                                                    33 
 34 关于每种KASAN模式的内存和性能影     34 关于每种KASAN模式的内存和性能影响的细节,请参见相应的Kconfig选项的描述。
 35                                                    35 
 36 通用模式和基于软件标签的模式通     36 通用模式和基于软件标签的模式通常被称为软件模式。基于软件标签的模式和基于
 37 硬件标签的模式被称为基于标签的     37 硬件标签的模式被称为基于标签的模式。
 38                                                    38 
 39 支持                                             39 支持
 40 ----                                               40 ----
 41                                                    41 
 42 体系架构                                       42 体系架构
 43 ~~~~~~~~                                           43 ~~~~~~~~
 44                                                    44 
 45 在x86_64、arm、arm64、powerpc、riscv、s3     45 在x86_64、arm、arm64、powerpc、riscv、s390、xtensa和loongarch上支持通用KASAN,
 46 而基于标签的KASAN模式只在arm64上支     46 而基于标签的KASAN模式只在arm64上支持。
 47                                                    47 
 48 编译器                                          48 编译器
 49 ~~~~~~                                             49 ~~~~~~
 50                                                    50 
 51 软件KASAN模式使用编译时工具在每     51 软件KASAN模式使用编译时工具在每个内存访问之前插入有效性检查,因此需要一个
 52 提供支持的编译器版本。基于硬件     52 提供支持的编译器版本。基于硬件标签的模式依靠硬件来执行这些检查,但仍然需要
 53 一个支持内存标签指令的编译器版     53 一个支持内存标签指令的编译器版本。
 54                                                    54 
 55 通用KASAN需要GCC 8.3.0版本或更高版     55 通用KASAN需要GCC 8.3.0版本或更高版本,或者内核支持的任何Clang版本。
 56                                                    56 
 57 基于软件标签的KASAN需要GCC 11+或者     57 基于软件标签的KASAN需要GCC 11+或者内核支持的任何Clang版本。
 58                                                    58 
 59 基于硬件标签的KASAN需要GCC 10+或Clan     59 基于硬件标签的KASAN需要GCC 10+或Clang 12+。
 60                                                    60 
 61 内存类型                                       61 内存类型
 62 ~~~~~~~~                                           62 ~~~~~~~~
 63                                                    63 
 64 通用KASAN支持在所有的slab、page_alloc     64 通用KASAN支持在所有的slab、page_alloc、vmap、vmalloc、堆栈和全局内存
 65 中查找错误。                                 65 中查找错误。
 66                                                    66 
 67 基于软件标签的KASAN支持slab、page_al     67 基于软件标签的KASAN支持slab、page_alloc、vmalloc和堆栈内存。
 68                                                    68 
 69 基于硬件标签的KASAN支持slab、page_al     69 基于硬件标签的KASAN支持slab、page_alloc和不可执行的vmalloc内存。
 70                                                    70 
 71 对于slab,两种软件KASAN模式都支持S     71 对于slab,两种软件KASAN模式都支持SLUB和SLAB分配器,而基于硬件标签的
 72 KASAN只支持SLUB。                              72 KASAN只支持SLUB。
 73                                                    73 
 74 用法                                             74 用法
 75 ----                                               75 ----
 76                                                    76 
 77 要启用KASAN,请使用以下命令配置     77 要启用KASAN,请使用以下命令配置内核::
 78                                                    78 
 79           CONFIG_KASAN=y                           79           CONFIG_KASAN=y
 80                                                    80 
 81 同时在 ``CONFIG_KASAN_GENERIC`` (启用通     81 同时在 ``CONFIG_KASAN_GENERIC`` (启用通用KASAN模式), ``CONFIG_KASAN_SW_TAGS``
 82 (启用基于硬件标签的KASAN模式),和     82 (启用基于硬件标签的KASAN模式),和 ``CONFIG_KASAN_HW_TAGS`` (启用基于硬件标签
 83 的KASAN模式)之间进行选择。               83 的KASAN模式)之间进行选择。
 84                                                    84 
 85 对于软件模式,还可以在 ``CONFIG_KAS     85 对于软件模式,还可以在 ``CONFIG_KASAN_OUTLINE`` 和 ``CONFIG_KASAN_INLINE``
 86 之间进行选择。outline和inline是编译     86 之间进行选择。outline和inline是编译器插桩类型。前者产生较小的二进制文件,
 87 而后者快2倍。                                87 而后者快2倍。
 88                                                    88 
 89 要将受影响的slab对象的alloc和free堆     89 要将受影响的slab对象的alloc和free堆栈跟踪包含到报告中,请启用
 90 ``CONFIG_STACKTRACE`` 。要包括受影响物     90 ``CONFIG_STACKTRACE`` 。要包括受影响物理页面的分配和释放堆栈跟踪的话,
 91 请启用 ``CONFIG_PAGE_OWNER`` 并使用 ``pa     91 请启用 ``CONFIG_PAGE_OWNER`` 并使用 ``page_owner=on`` 进行引导。
 92                                                    92 
 93 启动参数                                       93 启动参数
 94 ~~~~~~~~                                           94 ~~~~~~~~
 95                                                    95 
 96 KASAN受到通用 ``panic_on_warn`` 命令行     96 KASAN受到通用 ``panic_on_warn`` 命令行参数的影响。当它被启用时,KASAN
 97 在打印出错误报告后会使内核恐慌     97 在打印出错误报告后会使内核恐慌。
 98                                                    98 
 99 默认情况下,KASAN只对第一个无效     99 默认情况下,KASAN只对第一个无效的内存访问打印错误报告。使用
100 ``kasan_multi_shot``,KASAN对每一个无效    100 ``kasan_multi_shot``,KASAN对每一个无效的访问都打印一份报告。这会禁用
101 了KASAN报告的 ``panic_on_warn``。            101 了KASAN报告的 ``panic_on_warn``。
102                                                   102 
103 另外,独立于 ``panic_on_warn`` 、 ``kas    103 另外,独立于 ``panic_on_warn`` 、 ``kasan.fault=`` boot参数可以用
104 来控制恐慌和报告行为。                 104 来控制恐慌和报告行为。
105                                                   105 
106 - ``kasan.fault=report`` 或 ``=panic`` 控制    106 - ``kasan.fault=report`` 或 ``=panic`` 控制是否只打印KASAN report或
107   同时使内核恐慌(默认: ``report``    107   同时使内核恐慌(默认: ``report`` )。即使 ``kasan_multi_shot`` 被
108   启用,恐慌也会发生。                  108   启用,恐慌也会发生。
109                                                   109 
110 基于软件和硬件标签的KASAN模式(    110 基于软件和硬件标签的KASAN模式(见下面关于各种模式的部分)支持改变堆栈跟
111 踪收集行为:                                111 踪收集行为:
112                                                   112 
113 - ``kasan.stacktrace=off`` 或 ``=on`` 禁用    113 - ``kasan.stacktrace=off`` 或 ``=on`` 禁用或启用分配和释放堆栈痕
114   迹的收集(默认: ``on`` )。          114   迹的收集(默认: ``on`` )。
115                                                   115 
116 - ``kasan.stack_ring_size=<number of entries>`    116 - ``kasan.stack_ring_size=<number of entries>`` 指定堆栈环的条
117   目数(默认: ``32768`` )。             117   目数(默认: ``32768`` )。
118                                                   118 
119 基于硬件标签的KASAN模式是为了在    119 基于硬件标签的KASAN模式是为了在生产中作为一种安全缓解措施使用。因此,它
120 支持额外的启动参数,允许完全禁    120 支持额外的启动参数,允许完全禁用KASAN或控制其功能。
121                                                   121 
122 - ``kasan=off`` 或 ``=on`` 控制KASAN是否    122 - ``kasan=off`` 或 ``=on`` 控制KASAN是否被启用(默认: ``on`` )。
123                                                   123 
124 - ``kasan.mode=sync``, ``=async`` or ``=asymm`    124 - ``kasan.mode=sync``, ``=async`` or ``=asymm`` 控制KASAN是否
125   被配置为同步、异步或非对称的    125   被配置为同步、异步或非对称的执行模式(默认: ``同步`` )。
126   同步模式:当标签检查异常发生    126   同步模式:当标签检查异常发生时,会立即检测到不良访问。
127   异步模式:不良访问的检测是延    127   异步模式:不良访问的检测是延迟的。当标签检查异常发生时,信息被存储在硬
128   件中(对于arm64来说是在TFSR_EL1寄    128   件中(对于arm64来说是在TFSR_EL1寄存器中)。内核周期性地检查硬件,并\
129   且只在这些检查中报告标签异常    129   且只在这些检查中报告标签异常。
130   非对称模式:读取时同步检测不    130   非对称模式:读取时同步检测不良访问,写入时异步检测。
131                                                   131 
132 - ``kasan.vmalloc=off`` or ``=on`` 禁用或    132 - ``kasan.vmalloc=off`` or ``=on`` 禁用或启用vmalloc分配的标记(默认: ``on`` )。
133                                                   133 
134 错误报告                                      134 错误报告
135 ~~~~~~~~                                          135 ~~~~~~~~
136                                                   136 
137 典型的KASAN报告如下所示::                137 典型的KASAN报告如下所示::
138                                                   138 
139     ==========================================    139     ==================================================================
140     BUG: KASAN: slab-out-of-bounds in kmalloc_ !! 140     BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0xa8/0xbc [test_kasan]
141     Write of size 1 at addr ffff8801f44ec37b b    141     Write of size 1 at addr ffff8801f44ec37b by task insmod/2760
142                                                   142 
143     CPU: 1 PID: 2760 Comm: insmod Not tainted     143     CPU: 1 PID: 2760 Comm: insmod Not tainted 4.19.0-rc3+ #698
144     Hardware name: QEMU Standard PC (i440FX +     144     Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
145     Call Trace:                                   145     Call Trace:
146      dump_stack+0x94/0xd8                         146      dump_stack+0x94/0xd8
147      print_address_description+0x73/0x280         147      print_address_description+0x73/0x280
148      kasan_report+0x144/0x187                     148      kasan_report+0x144/0x187
149      __asan_report_store1_noabort+0x17/0x20       149      __asan_report_store1_noabort+0x17/0x20
150      kmalloc_oob_right+0xa8/0xbc [kasan_test]  !! 150      kmalloc_oob_right+0xa8/0xbc [test_kasan]
151      kmalloc_tests_init+0x16/0x700 [kasan_test !! 151      kmalloc_tests_init+0x16/0x700 [test_kasan]
152      do_one_initcall+0xa5/0x3ae                   152      do_one_initcall+0xa5/0x3ae
153      do_init_module+0x1b6/0x547                   153      do_init_module+0x1b6/0x547
154      load_module+0x75df/0x8070                    154      load_module+0x75df/0x8070
155      __do_sys_init_module+0x1c6/0x200             155      __do_sys_init_module+0x1c6/0x200
156      __x64_sys_init_module+0x6e/0xb0              156      __x64_sys_init_module+0x6e/0xb0
157      do_syscall_64+0x9f/0x2c0                     157      do_syscall_64+0x9f/0x2c0
158      entry_SYSCALL_64_after_hwframe+0x44/0xa9     158      entry_SYSCALL_64_after_hwframe+0x44/0xa9
159     RIP: 0033:0x7f96443109da                      159     RIP: 0033:0x7f96443109da
160     RSP: 002b:00007ffcf0b51b08 EFLAGS: 0000020    160     RSP: 002b:00007ffcf0b51b08 EFLAGS: 00000202 ORIG_RAX: 00000000000000af
161     RAX: ffffffffffffffda RBX: 000055dc3ee521a    161     RAX: ffffffffffffffda RBX: 000055dc3ee521a0 RCX: 00007f96443109da
162     RDX: 00007f96445cff88 RSI: 0000000000057a5    162     RDX: 00007f96445cff88 RSI: 0000000000057a50 RDI: 00007f9644992000
163     RBP: 000055dc3ee510b0 R08: 000000000000000    163     RBP: 000055dc3ee510b0 R08: 0000000000000003 R09: 0000000000000000
164     R10: 00007f964430cd0a R11: 000000000000020    164     R10: 00007f964430cd0a R11: 0000000000000202 R12: 00007f96445cff88
165     R13: 000055dc3ee51090 R14: 000000000000000    165     R13: 000055dc3ee51090 R14: 0000000000000000 R15: 0000000000000000
166                                                   166 
167     Allocated by task 2760:                       167     Allocated by task 2760:
168      save_stack+0x43/0xd0                         168      save_stack+0x43/0xd0
169      kasan_kmalloc+0xa7/0xd0                      169      kasan_kmalloc+0xa7/0xd0
170      kmem_cache_alloc_trace+0xe1/0x1b0            170      kmem_cache_alloc_trace+0xe1/0x1b0
171      kmalloc_oob_right+0x56/0xbc [kasan_test]  !! 171      kmalloc_oob_right+0x56/0xbc [test_kasan]
172      kmalloc_tests_init+0x16/0x700 [kasan_test !! 172      kmalloc_tests_init+0x16/0x700 [test_kasan]
173      do_one_initcall+0xa5/0x3ae                   173      do_one_initcall+0xa5/0x3ae
174      do_init_module+0x1b6/0x547                   174      do_init_module+0x1b6/0x547
175      load_module+0x75df/0x8070                    175      load_module+0x75df/0x8070
176      __do_sys_init_module+0x1c6/0x200             176      __do_sys_init_module+0x1c6/0x200
177      __x64_sys_init_module+0x6e/0xb0              177      __x64_sys_init_module+0x6e/0xb0
178      do_syscall_64+0x9f/0x2c0                     178      do_syscall_64+0x9f/0x2c0
179      entry_SYSCALL_64_after_hwframe+0x44/0xa9     179      entry_SYSCALL_64_after_hwframe+0x44/0xa9
180                                                   180 
181     Freed by task 815:                            181     Freed by task 815:
182      save_stack+0x43/0xd0                         182      save_stack+0x43/0xd0
183      __kasan_slab_free+0x135/0x190                183      __kasan_slab_free+0x135/0x190
184      kasan_slab_free+0xe/0x10                     184      kasan_slab_free+0xe/0x10
185      kfree+0x93/0x1a0                             185      kfree+0x93/0x1a0
186      umh_complete+0x6a/0xa0                       186      umh_complete+0x6a/0xa0
187      call_usermodehelper_exec_async+0x4c3/0x64    187      call_usermodehelper_exec_async+0x4c3/0x640
188      ret_from_fork+0x35/0x40                      188      ret_from_fork+0x35/0x40
189                                                   189 
190     The buggy address belongs to the object at    190     The buggy address belongs to the object at ffff8801f44ec300
191      which belongs to the cache kmalloc-128 of    191      which belongs to the cache kmalloc-128 of size 128
192     The buggy address is located 123 bytes ins    192     The buggy address is located 123 bytes inside of
193      128-byte region [ffff8801f44ec300, ffff88    193      128-byte region [ffff8801f44ec300, ffff8801f44ec380)
194     The buggy address belongs to the page:        194     The buggy address belongs to the page:
195     page:ffffea0007d13b00 count:1 mapcount:0 m    195     page:ffffea0007d13b00 count:1 mapcount:0 mapping:ffff8801f7001640 index:0x0
196     flags: 0x200000000000100(slab)                196     flags: 0x200000000000100(slab)
197     raw: 0200000000000100 ffffea0007d11dc0 000    197     raw: 0200000000000100 ffffea0007d11dc0 0000001a0000001a ffff8801f7001640
198     raw: 0000000000000000 0000000080150015 000    198     raw: 0000000000000000 0000000080150015 00000001ffffffff 0000000000000000
199     page dumped because: kasan: bad access det    199     page dumped because: kasan: bad access detected
200                                                   200 
201     Memory state around the buggy address:        201     Memory state around the buggy address:
202      ffff8801f44ec200: fc fc fc fc fc fc fc fc    202      ffff8801f44ec200: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
203      ffff8801f44ec280: fb fb fb fb fb fb fb fb    203      ffff8801f44ec280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
204     >ffff8801f44ec300: 00 00 00 00 00 00 00 00    204     >ffff8801f44ec300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
205                                                   205                                                                     ^
206      ffff8801f44ec380: fc fc fc fc fc fc fc fc    206      ffff8801f44ec380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
207      ffff8801f44ec400: fb fb fb fb fb fb fb fb    207      ffff8801f44ec400: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
208     ==========================================    208     ==================================================================
209                                                   209 
210 报告标题总结了发生的错误类型以    210 报告标题总结了发生的错误类型以及导致该错误的访问类型。紧随其后的是错误访问的
211 堆栈跟踪、所访问内存分配位置的    211 堆栈跟踪、所访问内存分配位置的堆栈跟踪(对于访问了slab对象的情况)以及对象
212 被释放的位置的堆栈跟踪(对于访    212 被释放的位置的堆栈跟踪(对于访问已释放内存的问题报告)。接下来是对访问的
213 slab对象的描述以及关于访问的内存    213 slab对象的描述以及关于访问的内存页的信息。
214                                                   214 
215 最后,报告展示了访问地址周围的    215 最后,报告展示了访问地址周围的内存状态。在内部,KASAN单独跟踪每个内存颗粒的
216 内存状态,根据KASAN模式分为8或16    216 内存状态,根据KASAN模式分为8或16个对齐字节。报告的内存状态部分中的每个数字
217 都显示了围绕访问地址的其中一个    217 都显示了围绕访问地址的其中一个内存颗粒的状态。
218                                                   218 
219 对于通用KASAN,每个内存颗粒的大    219 对于通用KASAN,每个内存颗粒的大小为8个字节。每个颗粒的状态被编码在一个影子字节
220 中。这8个字节可以是可访问的,部    220 中。这8个字节可以是可访问的,部分访问的,已释放的或成为Redzone的一部分。KASAN
221 对每个影子字节使用以下编码:00表    221 对每个影子字节使用以下编码:00表示对应内存区域的所有8个字节都可以访问;数字N
222 (1 <= N <= 7)表示前N个字节可访问,    222 (1 <= N <= 7)表示前N个字节可访问,其他(8 - N)个字节不可访问;任何负值都表示
223 无法访问整个8字节。KASAN使用不同    223 无法访问整个8字节。KASAN使用不同的负值来区分不同类型的不可访问内存,如redzones
224 或已释放的内存(参见 mm/kasan/kasan.    224 或已释放的内存(参见 mm/kasan/kasan.h)。
225                                                   225 
226 在上面的报告中,箭头指向影子字    226 在上面的报告中,箭头指向影子字节 ``03`` ,表示访问的地址是部分可访问的。
227                                                   227 
228 对于基于标签的KASAN模式,报告最    228 对于基于标签的KASAN模式,报告最后的部分显示了访问地址周围的内存标签
229 (参考 `实施细则`_ 章节)。                229 (参考 `实施细则`_ 章节)。
230                                                   230 
231 请注意,KASAN错误标题(如 ``slab-out    231 请注意,KASAN错误标题(如 ``slab-out-of-bounds`` 或 ``use-after-free`` )
232 是尽量接近的:KASAN根据其拥有的有    232 是尽量接近的:KASAN根据其拥有的有限信息打印出最可能的错误类型。错误的实际类型
233 可能会有所不同。                          233 可能会有所不同。
234                                                   234 
235 通用KASAN还报告两个辅助调用堆栈    235 通用KASAN还报告两个辅助调用堆栈跟踪。这些堆栈跟踪指向代码中与对象交互但不直接
236 出现在错误访问堆栈跟踪中的位置    236 出现在错误访问堆栈跟踪中的位置。目前,这包括 call_rcu() 和排队的工作队列。
237                                                   237 
238 CONFIG_KASAN_EXTRA_INFO                        << 
239 ~~~~~~~~~~~~~~~~~~~~~~~                        << 
240                                                << 
241 启用 CONFIG_KASAN_EXTRA_INFO 选项允许 KA << 
242 额外信息包括分配和释放时的 CPU  << 
243 并将错误与其他系统事件关联起来 << 
244 开销的细节,请参见 CONFIG_KASAN_EXTRA << 
245                                                << 
246 以下为 CONFIG_KASAN_EXTRA_INFO 开启后的 << 
247                                                << 
248     ========================================== << 
249     ...                                        << 
250     Allocated by task 134 on cpu 5 at 229.1338 << 
251     ...                                        << 
252     Freed by task 136 on cpu 3 at 230.199335s: << 
253     ...                                        << 
254     ========================================== << 
255                                                << 
256 实施细则                                      238 实施细则
257 --------                                          239 --------
258                                                   240 
259 通用KASAN                                       241 通用KASAN
260 ~~~~~~~~~                                         242 ~~~~~~~~~
261                                                   243 
262 软件KASAN模式使用影子内存来记录    244 软件KASAN模式使用影子内存来记录每个内存字节是否可以安全访问,并使用编译时工具
263 在每次内存访问之前插入影子内存    245 在每次内存访问之前插入影子内存检查。
264                                                   246 
265 通用KASAN将1/8的内核内存专用于其    247 通用KASAN将1/8的内核内存专用于其影子内存(16TB以覆盖x86_64上的128TB),并使用
266 具有比例和偏移量的直接映射将内    248 具有比例和偏移量的直接映射将内存地址转换为其相应的影子地址。
267                                                   249 
268 这是将地址转换为其相应影子地址    250 这是将地址转换为其相应影子地址的函数::
269                                                   251 
270     static inline void *kasan_mem_to_shadow(co    252     static inline void *kasan_mem_to_shadow(const void *addr)
271     {                                             253     {
272         return (void *)((unsigned long)addr >>    254         return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
273                 + KASAN_SHADOW_OFFSET;            255                 + KASAN_SHADOW_OFFSET;
274     }                                             256     }
275                                                   257 
276 在这里 ``KASAN_SHADOW_SCALE_SHIFT = 3`` 。    258 在这里 ``KASAN_SHADOW_SCALE_SHIFT = 3`` 。
277                                                   259 
278 编译时工具用于插入内存访问检查    260 编译时工具用于插入内存访问检查。编译器在每次访问大小为1、2、4、8或16的内存之前
279 插入函数调用( ``__asan_load*(addr)`` , `    261 插入函数调用( ``__asan_load*(addr)`` , ``__asan_store*(addr)``)。这些函数通过
280 检查相应的影子内存来检查内存访    262 检查相应的影子内存来检查内存访问是否有效。
281                                                   263 
282 使用inline插桩,编译器不进行函数    264 使用inline插桩,编译器不进行函数调用,而是直接插入代码来检查影子内存。此选项
283 显著地增大了内核体积,但与outline    265 显著地增大了内核体积,但与outline插桩内核相比,它提供了x1.1-x2的性能提升。
284                                                   266 
285 通用KASAN是唯一一种通过隔离延迟    267 通用KASAN是唯一一种通过隔离延迟重新使用已释放对象的模式
286 (参见 mm/kasan/quarantine.c 以了解实    268 (参见 mm/kasan/quarantine.c 以了解实现)。
287                                                   269 
288 基于软件标签的KASAN模式                  270 基于软件标签的KASAN模式
289 ~~~~~~~~~~~~~~~~~~~~~~~                           271 ~~~~~~~~~~~~~~~~~~~~~~~
290                                                   272 
291 基于软件标签的KASAN使用软件内存    273 基于软件标签的KASAN使用软件内存标签方法来检查访问有效性。目前仅针对arm64架构实现。
292                                                   274 
293 基于软件标签的KASAN使用arm64 CPU的    275 基于软件标签的KASAN使用arm64 CPU的顶部字节忽略(TBI)特性在内核指针的顶部字节中
294 存储一个指针标签。它使用影子内    276 存储一个指针标签。它使用影子内存来存储与每个16字节内存单元相关的内存标签(因此,
295 它将内核内存的1/16专用于影子内存    277 它将内核内存的1/16专用于影子内存)。
296                                                   278 
297 在每次内存分配时,基于软件标签    279 在每次内存分配时,基于软件标签的KASAN都会生成一个随机标签,用这个标签标记分配
298 的内存,并将相同的标签嵌入到返    280 的内存,并将相同的标签嵌入到返回的指针中。
299                                                   281 
300 基于软件标签的KASAN使用编译时工    282 基于软件标签的KASAN使用编译时工具在每次内存访问之前插入检查。这些检查确保正在
301 访问的内存的标签等于用于访问该    283 访问的内存的标签等于用于访问该内存的指针的标签。如果标签不匹配,基于软件标签
302 的KASAN会打印错误报告。                  284 的KASAN会打印错误报告。
303                                                   285 
304 基于软件标签的KASAN也有两种插桩    286 基于软件标签的KASAN也有两种插桩模式(outline,发出回调来检查内存访问;inline,
305 执行内联的影子内存检查)。使用o    287 执行内联的影子内存检查)。使用outline插桩模式,会从执行访问检查的函数打印错误
306 报告。使用inline插桩,编译器会发    288 报告。使用inline插桩,编译器会发出 ``brk`` 指令,并使用专用的 ``brk`` 处理程序
307 来打印错误报告。                          289 来打印错误报告。
308                                                   290 
309 基于软件标签的KASAN使用0xFF作为匹    291 基于软件标签的KASAN使用0xFF作为匹配所有指针标签(不检查通过带有0xFF指针标签
310 的指针进行的访问)。值0xFE当前保    292 的指针进行的访问)。值0xFE当前保留用于标记已释放的内存区域。
311                                                   293 
312                                                   294 
313 基于硬件标签的KASAN模式                  295 基于硬件标签的KASAN模式
314 ~~~~~~~~~~~~~~~~~~~~~~~                           296 ~~~~~~~~~~~~~~~~~~~~~~~
315                                                   297 
316 基于硬件标签的KASAN在概念上类似    298 基于硬件标签的KASAN在概念上类似于软件模式,但它是使用硬件内存标签作为支持而
317 不是编译器插桩和影子内存。           299 不是编译器插桩和影子内存。
318                                                   300 
319 基于硬件标签的KASAN目前仅针对arm64    301 基于硬件标签的KASAN目前仅针对arm64架构实现,并且基于ARMv8.5指令集架构中引入
320 的arm64内存标记扩展(MTE)和最高字节    302 的arm64内存标记扩展(MTE)和最高字节忽略(TBI)。
321                                                   303 
322 特殊的arm64指令用于为每次内存分    304 特殊的arm64指令用于为每次内存分配指定内存标签。相同的标签被指定给指向这些分配
323 的指针。在每次内存访问时,硬件    305 的指针。在每次内存访问时,硬件确保正在访问的内存的标签等于用于访问该内存的指针
324 的标签。如果标签不匹配,则会生    306 的标签。如果标签不匹配,则会生成故障并打印报告。
325                                                   307 
326 基于硬件标签的KASAN使用0xFF作为匹    308 基于硬件标签的KASAN使用0xFF作为匹配所有指针标签(不检查通过带有0xFF指针标签的
327 指针进行的访问)。值0xFE当前保留    309 指针进行的访问)。值0xFE当前保留用于标记已释放的内存区域。
328                                                   310 
329 如果硬件不支持MTE(ARMv8.5之前),    311 如果硬件不支持MTE(ARMv8.5之前),则不会启用基于硬件标签的KASAN。在这种情况下,
330 所有KASAN引导参数都将被忽略。         312 所有KASAN引导参数都将被忽略。
331                                                   313 
332 请注意,启用CONFIG_KASAN_HW_TAGS始终    314 请注意,启用CONFIG_KASAN_HW_TAGS始终会导致启用内核中的TBI。即使提供了
333 ``kasan.mode=off`` 或硬件不支持MTE(但    315 ``kasan.mode=off`` 或硬件不支持MTE(但支持TBI)。
334                                                   316 
335 基于硬件标签的KASAN只报告第一个    317 基于硬件标签的KASAN只报告第一个发现的错误。之后,MTE标签检查将被禁用。
336                                                   318 
337 影子内存                                      319 影子内存
338 --------                                          320 --------
339                                                   321 
340 本节的内容只适用于软件KASAN模式    322 本节的内容只适用于软件KASAN模式。
341                                                   323 
342 内核将内存映射到地址空间的几个    324 内核将内存映射到地址空间的几个不同部分。内核虚拟地址的范围很大:没有足够的真实
343 内存来支持内核可以访问的每个地    325 内存来支持内核可以访问的每个地址的真实影子区域。因此,KASAN只为地址空间的某些
344 部分映射真实的影子。                    326 部分映射真实的影子。
345                                                   327 
346 默认行为                                      328 默认行为
347 ~~~~~~~~                                          329 ~~~~~~~~
348                                                   330 
349 默认情况下,体系结构仅将实际内    331 默认情况下,体系结构仅将实际内存映射到用于线性映射的阴影区域(以及可能的其他
350 小区域)。对于所有其他区域 ——    332 小区域)。对于所有其他区域 —— 例如vmalloc和vmemmap空间 —— 一个只读页面被映射
351 到阴影区域上。这个只读的影子页    333 到阴影区域上。这个只读的影子页面声明所有内存访问都是允许的。
352                                                   334 
353 这给模块带来了一个问题:它们不    335 这给模块带来了一个问题:它们不存在于线性映射中,而是存在于专用的模块空间中。
354 通过连接模块分配器,KASAN临时映    336 通过连接模块分配器,KASAN临时映射真实的影子内存以覆盖它们。例如,这允许检测
355 对模块全局变量的无效访问。           337 对模块全局变量的无效访问。
356                                                   338 
357 这也造成了与 ``VMAP_STACK`` 的不兼容    339 这也造成了与 ``VMAP_STACK`` 的不兼容:如果堆栈位于vmalloc空间中,它将被分配
358 只读页面的影子内存,并且内核在    340 只读页面的影子内存,并且内核在尝试为堆栈变量设置影子数据时会出错。
359                                                   341 
360 CONFIG_KASAN_VMALLOC                              342 CONFIG_KASAN_VMALLOC
361 ~~~~~~~~~~~~~~~~~~~~                              343 ~~~~~~~~~~~~~~~~~~~~
362                                                   344 
363 使用 ``CONFIG_KASAN_VMALLOC`` ,KASAN可以    345 使用 ``CONFIG_KASAN_VMALLOC`` ,KASAN可以以更大的内存使用为代价覆盖vmalloc
364 空间。目前,这在arm64、x86、riscv、    346 空间。目前,这在arm64、x86、riscv、s390和powerpc上受支持。
365                                                   347 
366 这通过连接到vmalloc和vmap并动态分    348 这通过连接到vmalloc和vmap并动态分配真实的影子内存来支持映射。
367                                                   349 
368 vmalloc空间中的大多数映射都很小,    350 vmalloc空间中的大多数映射都很小,需要不到一整页的阴影空间。因此,为每个映射
369 分配一个完整的影子页面将是一种    351 分配一个完整的影子页面将是一种浪费。此外,为了确保不同的映射使用不同的影子
370 页面,映射必须与 ``KASAN_GRANULE_SIZE     352 页面,映射必须与 ``KASAN_GRANULE_SIZE * PAGE_SIZE`` 对齐。
371                                                   353 
372 相反,KASAN跨多个映射共享后备空    354 相反,KASAN跨多个映射共享后备空间。当vmalloc空间中的映射使用影子区域的特定
373 页面时,它会分配一个后备页面。    355 页面时,它会分配一个后备页面。此页面稍后可以由其他vmalloc映射共享。
374                                                   356 
375 KASAN连接到vmap基础架构以懒清理未    357 KASAN连接到vmap基础架构以懒清理未使用的影子内存。
376                                                   358 
377 为了避免交换映射的困难,KASAN预    359 为了避免交换映射的困难,KASAN预测覆盖vmalloc空间的阴影区域部分将不会被早期
378 的阴影页面覆盖,但是将不会被映    360 的阴影页面覆盖,但是将不会被映射。这将需要更改特定于arch的代码。
379                                                   361 
380 这允许在x86上支持 ``VMAP_STACK`` ,并    362 这允许在x86上支持 ``VMAP_STACK`` ,并且可以简化对没有固定模块区域的架构的支持。
381                                                   363 
382 对于开发者                                   364 对于开发者
383 ----------                                        365 ----------
384                                                   366 
385 忽略访问                                      367 忽略访问
386 ~~~~~~~~                                          368 ~~~~~~~~
387                                                   369 
388 软件KASAN模式使用编译器插桩来插    370 软件KASAN模式使用编译器插桩来插入有效性检查。此类检测可能与内核的某些部分
389 不兼容,因此需要禁用。                 371 不兼容,因此需要禁用。
390                                                   372 
391 内核的其他部分可能会访问已分配    373 内核的其他部分可能会访问已分配对象的元数据。通常,KASAN会检测并报告此类访问,
392 但在某些情况下(例如,在内存分    374 但在某些情况下(例如,在内存分配器中),这些访问是有效的。
393                                                   375 
394 对于软件KASAN模式,要禁用特定文    376 对于软件KASAN模式,要禁用特定文件或目录的检测,请将 ``KASAN_SANITIZE`` 添加
395 到相应的内核Makefile中:                    377 到相应的内核Makefile中:
396                                                   378 
397 - 对于单个文件(例如,main.o)::           379 - 对于单个文件(例如,main.o)::
398                                                   380 
399     KASAN_SANITIZE_main.o := n                    381     KASAN_SANITIZE_main.o := n
400                                                   382 
401 - 对于一个目录下的所有文件::          383 - 对于一个目录下的所有文件::
402                                                   384 
403     KASAN_SANITIZE := n                           385     KASAN_SANITIZE := n
404                                                   386 
405 对于软件KASAN模式,要在每个函数    387 对于软件KASAN模式,要在每个函数的基础上禁用检测,请使用KASAN特定的
406 ``__no_sanitize_address`` 函数属性或通    388 ``__no_sanitize_address`` 函数属性或通用的 ``noinstr`` 。
407                                                   389 
408 请注意,禁用编译器插桩(基于每    390 请注意,禁用编译器插桩(基于每个文件或每个函数)会使KASAN忽略在软件KASAN模式
409 的代码中直接发生的访问。当访问    391 的代码中直接发生的访问。当访问是间接发生的(通过调用检测函数)或使用没有编译器
410 插桩的基于硬件标签的模式时,它    392 插桩的基于硬件标签的模式时,它没有帮助。
411                                                   393 
412 对于软件KASAN模式,要在当前任务    394 对于软件KASAN模式,要在当前任务的一部分内核代码中禁用KASAN报告,请使用
413 ``kasan_disable_current()``/``kasan_enable_cur    395 ``kasan_disable_current()``/``kasan_enable_current()`` 部分注释这部分代码。
414 这也会禁用通过函数调用发生的间    396 这也会禁用通过函数调用发生的间接访问的报告。
415                                                   397 
416 对于基于标签的KASAN模式,要禁用    398 对于基于标签的KASAN模式,要禁用访问检查,请使用 ``kasan_reset_tag()`` 或
417 ``page_kasan_tag_reset()`` 。请注意,通    399 ``page_kasan_tag_reset()`` 。请注意,通过 ``page_kasan_tag_reset()``
418 临时禁用访问检查需要通过 ``page_ka    400 临时禁用访问检查需要通过 ``page_kasan_tag`` / ``page_kasan_tag_set`` 保
419 存和恢复每页KASAN标签。                  401 存和恢复每页KASAN标签。
420                                                   402 
421 测试                                            403 测试
422 ~~~~                                              404 ~~~~
423                                                   405 
424 有一些KASAN测试可以验证KASAN是否正    406 有一些KASAN测试可以验证KASAN是否正常工作并可以检测某些类型的内存损坏。
425 测试由两部分组成:                         407 测试由两部分组成:
426                                                   408 
427 1. 与KUnit测试框架集成的测试。使    409 1. 与KUnit测试框架集成的测试。使用 ``CONFIG_KASAN_KUNIT_TEST`` 启用。
428 这些测试可以通过几种不同的方式    410 这些测试可以通过几种不同的方式自动运行和部分验证;请参阅下面的说明。
429                                                   411 
430 2. 与KUnit不兼容的测试。使用 ``CONFI    412 2. 与KUnit不兼容的测试。使用 ``CONFIG_KASAN_MODULE_TEST`` 启用并且只能作为模块
431 运行。这些测试只能通过加载内核    413 运行。这些测试只能通过加载内核模块并检查内核日志以获取KASAN报告来手动验证。
432                                                   414 
433 如果检测到错误,每个KUnit兼容的KA    415 如果检测到错误,每个KUnit兼容的KASAN测试都会打印多个KASAN报告之一,然后测试打印
434 其编号和状态。                             416 其编号和状态。
435                                                   417 
436 当测试通过::                                 418 当测试通过::
437                                                   419 
438         ok 28 - kmalloc_double_kzfree             420         ok 28 - kmalloc_double_kzfree
439                                                   421 
440 当由于 ``kmalloc`` 失败而导致测试失    422 当由于 ``kmalloc`` 失败而导致测试失败时::
441                                                   423 
442         # kmalloc_large_oob_right: ASSERTION F !! 424         # kmalloc_large_oob_right: ASSERTION FAILED at lib/test_kasan.c:163
443         Expected ptr is not null, but is          425         Expected ptr is not null, but is
444         not ok 5 - kmalloc_large_oob_right     !! 426         not ok 4 - kmalloc_large_oob_right
445                                                   427 
446 当由于缺少KASAN报告而导致测试失    428 当由于缺少KASAN报告而导致测试失败时::
447                                                   429 
448         # kmalloc_double_kzfree: EXPECTATION F !! 430         # kmalloc_double_kzfree: EXPECTATION FAILED at lib/test_kasan.c:974
449         KASAN failure expected in "kfree_sensi    431         KASAN failure expected in "kfree_sensitive(ptr)", but none occurred
450         not ok 28 - kmalloc_double_kzfree      !! 432         not ok 44 - kmalloc_double_kzfree
451                                                   433 
452                                                   434 
453 最后打印所有KASAN测试的累积状态    435 最后打印所有KASAN测试的累积状态。成功::
454                                                   436 
455         ok 1 - kasan                              437         ok 1 - kasan
456                                                   438 
457 或者,如果其中一项测试失败::         439 或者,如果其中一项测试失败::
458                                                   440 
459         not ok 1 - kasan                          441         not ok 1 - kasan
460                                                   442 
461 有几种方法可以运行与KUnit兼容的KA    443 有几种方法可以运行与KUnit兼容的KASAN测试。
462                                                   444 
463 1. 可加载模块                                445 1. 可加载模块
464                                                   446 
465    启用 ``CONFIG_KUNIT`` 后,KASAN-KUnit    447    启用 ``CONFIG_KUNIT`` 后,KASAN-KUnit测试可以构建为可加载模块,并通过使用
466    ``insmod`` 或 ``modprobe`` 加载 ``kasan_ !! 448    ``insmod`` 或 ``modprobe`` 加载 ``test_kasan.ko`` 来运行。
467                                                   449 
468 2. 内置                                         450 2. 内置
469                                                   451 
470    通过内置 ``CONFIG_KUNIT`` ,也可以    452    通过内置 ``CONFIG_KUNIT`` ,也可以内置KASAN-KUnit测试。在这种情况下,
471    测试将在启动时作为后期初始化    453    测试将在启动时作为后期初始化调用运行。
472                                                   454 
473 3. 使用kunit_tool                               455 3. 使用kunit_tool
474                                                   456 
475    通过内置 ``CONFIG_KUNIT`` 和 ``CONFIG_    457    通过内置 ``CONFIG_KUNIT`` 和 ``CONFIG_KASAN_KUNIT_TEST`` ,还可以使用
476    ``kunit_tool`` 以更易读的方式查看K    458    ``kunit_tool`` 以更易读的方式查看KUnit测试结果。这不会打印通过测试
477    的KASAN报告。有关 ``kunit_tool`` 更    459    的KASAN报告。有关 ``kunit_tool`` 更多最新信息,请参阅
478    `KUnit文档 <https://www.kernel.org/doc/ht    460    `KUnit文档 <https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html>`_ 。
479                                                   461 
480 .. _KUnit: https://www.kernel.org/doc/html/lat    462 .. _KUnit: https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php