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

TOMOYO Linux Cross Reference
Linux/Documentation/translations/zh_TW/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_TW/dev-tools/kasan.rst (Architecture i386) and /Documentation/translations/zh_TW/dev-tools/kasan.rst (Architecture sparc)


  1 .. SPDX-License-Identifier: GPL-2.0                 1 .. SPDX-License-Identifier: GPL-2.0
  2                                                     2 
  3 .. include:: ../disclaimer-zh_TW.rst                3 .. include:: ../disclaimer-zh_TW.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 [kasan_test]
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 [kasan_test]
151      kmalloc_tests_init+0x16/0x700 [kasan_test    151      kmalloc_tests_init+0x16/0x700 [kasan_test]
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 [kasan_test]
172      kmalloc_tests_init+0x16/0x700 [kasan_test    172      kmalloc_tests_init+0x16/0x700 [kasan_test]
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 實施細則                                      238 實施細則
239 --------                                          239 --------
240                                                   240 
241 通用KASAN                                       241 通用KASAN
242 ~~~~~~~~~                                         242 ~~~~~~~~~
243                                                   243 
244 軟件KASAN模式使用影子內存來記錄    244 軟件KASAN模式使用影子內存來記錄每個內存字節是否可以安全訪問,並使用編譯時工具
245 在每次內存訪問之前插入影子內存    245 在每次內存訪問之前插入影子內存檢查。
246                                                   246 
247 通用KASAN將1/8的內核內存專用於其    247 通用KASAN將1/8的內核內存專用於其影子內存(16TB以覆蓋x86_64上的128TB),並使用
248 具有比例和偏移量的直接映射將內    248 具有比例和偏移量的直接映射將內存地址轉換爲其相應的影子地址。
249                                                   249 
250 這是將地址轉換爲其相應影子地址    250 這是將地址轉換爲其相應影子地址的函數::
251                                                   251 
252     static inline void *kasan_mem_to_shadow(co    252     static inline void *kasan_mem_to_shadow(const void *addr)
253     {                                             253     {
254         return (void *)((unsigned long)addr >>    254         return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
255                 + KASAN_SHADOW_OFFSET;            255                 + KASAN_SHADOW_OFFSET;
256     }                                             256     }
257                                                   257 
258 在這裏 ``KASAN_SHADOW_SCALE_SHIFT = 3`` 。    258 在這裏 ``KASAN_SHADOW_SCALE_SHIFT = 3`` 。
259                                                   259 
260 編譯時工具用於插入內存訪問檢查    260 編譯時工具用於插入內存訪問檢查。編譯器在每次訪問大小爲1、2、4、8或16的內存之前
261 插入函數調用( ``__asan_load*(addr)`` , `    261 插入函數調用( ``__asan_load*(addr)`` , ``__asan_store*(addr)``)。這些函數通過
262 檢查相應的影子內存來檢查內存訪    262 檢查相應的影子內存來檢查內存訪問是否有效。
263                                                   263 
264 使用inline插樁,編譯器不進行函數    264 使用inline插樁,編譯器不進行函數調用,而是直接插入代碼來檢查影子內存。此選項
265 顯著地增大了內核體積,但與outline    265 顯著地增大了內核體積,但與outline插樁內核相比,它提供了x1.1-x2的性能提升。
266                                                   266 
267 通用KASAN是唯一一種通過隔離延遲    267 通用KASAN是唯一一種通過隔離延遲重新使用已釋放對象的模式
268 (參見 mm/kasan/quarantine.c 以瞭解實    268 (參見 mm/kasan/quarantine.c 以瞭解實現)。
269                                                   269 
270 基於軟件標籤的KASAN模式                  270 基於軟件標籤的KASAN模式
271 ~~~~~~~~~~~~~~~~~~~~~~~                           271 ~~~~~~~~~~~~~~~~~~~~~~~
272                                                   272 
273 基於軟件標籤的KASAN使用軟件內存    273 基於軟件標籤的KASAN使用軟件內存標籤方法來檢查訪問有效性。目前僅針對arm64架構實現。
274                                                   274 
275 基於軟件標籤的KASAN使用arm64 CPU的    275 基於軟件標籤的KASAN使用arm64 CPU的頂部字節忽略(TBI)特性在內核指針的頂部字節中
276 存儲一個指針標籤。它使用影子內    276 存儲一個指針標籤。它使用影子內存來存儲與每個16字節內存單元相關的內存標籤(因此,
277 它將內核內存的1/16專用於影子內存    277 它將內核內存的1/16專用於影子內存)。
278                                                   278 
279 在每次內存分配時,基於軟件標籤    279 在每次內存分配時,基於軟件標籤的KASAN都會生成一個隨機標籤,用這個標籤標記分配
280 的內存,並將相同的標籤嵌入到返    280 的內存,並將相同的標籤嵌入到返回的指針中。
281                                                   281 
282 基於軟件標籤的KASAN使用編譯時工    282 基於軟件標籤的KASAN使用編譯時工具在每次內存訪問之前插入檢查。這些檢查確保正在
283 訪問的內存的標籤等於用於訪問該    283 訪問的內存的標籤等於用於訪問該內存的指針的標籤。如果標籤不匹配,基於軟件標籤
284 的KASAN會打印錯誤報告。                  284 的KASAN會打印錯誤報告。
285                                                   285 
286 基於軟件標籤的KASAN也有兩種插樁    286 基於軟件標籤的KASAN也有兩種插樁模式(outline,發出回調來檢查內存訪問;inline,
287 執行內聯的影子內存檢查)。使用o    287 執行內聯的影子內存檢查)。使用outline插樁模式,會從執行訪問檢查的函數打印錯誤
288 報告。使用inline插樁,編譯器會發    288 報告。使用inline插樁,編譯器會發出 ``brk`` 指令,並使用專用的 ``brk`` 處理程序
289 來打印錯誤報告。                          289 來打印錯誤報告。
290                                                   290 
291 基於軟件標籤的KASAN使用0xFF作爲匹    291 基於軟件標籤的KASAN使用0xFF作爲匹配所有指針標籤(不檢查通過帶有0xFF指針標籤
292 的指針進行的訪問)。值0xFE當前保    292 的指針進行的訪問)。值0xFE當前保留用於標記已釋放的內存區域。
293                                                   293 
294                                                   294 
295 基於硬件標籤的KASAN模式                  295 基於硬件標籤的KASAN模式
296 ~~~~~~~~~~~~~~~~~~~~~~~                           296 ~~~~~~~~~~~~~~~~~~~~~~~
297                                                   297 
298 基於硬件標籤的KASAN在概念上類似    298 基於硬件標籤的KASAN在概念上類似於軟件模式,但它是使用硬件內存標籤作爲支持而
299 不是編譯器插樁和影子內存。           299 不是編譯器插樁和影子內存。
300                                                   300 
301 基於硬件標籤的KASAN目前僅針對arm64    301 基於硬件標籤的KASAN目前僅針對arm64架構實現,並且基於ARMv8.5指令集架構中引入
302 的arm64內存標記擴展(MTE)和最高字節    302 的arm64內存標記擴展(MTE)和最高字節忽略(TBI)。
303                                                   303 
304 特殊的arm64指令用於爲每次內存分    304 特殊的arm64指令用於爲每次內存分配指定內存標籤。相同的標籤被指定給指向這些分配
305 的指針。在每次內存訪問時,硬件    305 的指針。在每次內存訪問時,硬件確保正在訪問的內存的標籤等於用於訪問該內存的指針
306 的標籤。如果標籤不匹配,則會生    306 的標籤。如果標籤不匹配,則會生成故障並打印報告。
307                                                   307 
308 基於硬件標籤的KASAN使用0xFF作爲匹    308 基於硬件標籤的KASAN使用0xFF作爲匹配所有指針標籤(不檢查通過帶有0xFF指針標籤的
309 指針進行的訪問)。值0xFE當前保留    309 指針進行的訪問)。值0xFE當前保留用於標記已釋放的內存區域。
310                                                   310 
311 如果硬件不支持MTE(ARMv8.5之前),    311 如果硬件不支持MTE(ARMv8.5之前),則不會啓用基於硬件標籤的KASAN。在這種情況下,
312 所有KASAN引導參數都將被忽略。         312 所有KASAN引導參數都將被忽略。
313                                                   313 
314 請注意,啓用CONFIG_KASAN_HW_TAGS始終    314 請注意,啓用CONFIG_KASAN_HW_TAGS始終會導致啓用內核中的TBI。即使提供了
315 ``kasan.mode=off`` 或硬件不支持MTE(但    315 ``kasan.mode=off`` 或硬件不支持MTE(但支持TBI)。
316                                                   316 
317 基於硬件標籤的KASAN只報告第一個    317 基於硬件標籤的KASAN只報告第一個發現的錯誤。之後,MTE標籤檢查將被禁用。
318                                                   318 
319 影子內存                                      319 影子內存
320 --------                                          320 --------
321                                                   321 
322 本節的內容只適用於軟件KASAN模式    322 本節的內容只適用於軟件KASAN模式。
323                                                   323 
324 內核將內存映射到地址空間的幾個    324 內核將內存映射到地址空間的幾個不同部分。內核虛擬地址的範圍很大:沒有足夠的真實
325 內存來支持內核可以訪問的每個地    325 內存來支持內核可以訪問的每個地址的真實影子區域。因此,KASAN只爲地址空間的某些
326 部分映射真實的影子。                    326 部分映射真實的影子。
327                                                   327 
328 默認行爲                                      328 默認行爲
329 ~~~~~~~~                                          329 ~~~~~~~~
330                                                   330 
331 默認情況下,體系結構僅將實際內    331 默認情況下,體系結構僅將實際內存映射到用於線性映射的陰影區域(以及可能的其他
332 小區域)。對於所有其他區域 ——    332 小區域)。對於所有其他區域 —— 例如vmalloc和vmemmap空間 —— 一個只讀頁面被映射
333 到陰影區域上。這個只讀的影子頁    333 到陰影區域上。這個只讀的影子頁面聲明所有內存訪問都是允許的。
334                                                   334 
335 這給模塊帶來了一個問題:它們不    335 這給模塊帶來了一個問題:它們不存在於線性映射中,而是存在於專用的模塊空間中。
336 通過連接模塊分配器,KASAN臨時映    336 通過連接模塊分配器,KASAN臨時映射真實的影子內存以覆蓋它們。例如,這允許檢測
337 對模塊全局變量的無效訪問。           337 對模塊全局變量的無效訪問。
338                                                   338 
339 這也造成了與 ``VMAP_STACK`` 的不兼容    339 這也造成了與 ``VMAP_STACK`` 的不兼容:如果堆棧位於vmalloc空間中,它將被分配
340 只讀頁面的影子內存,並且內核在    340 只讀頁面的影子內存,並且內核在嘗試爲堆棧變量設置影子數據時會出錯。
341                                                   341 
342 CONFIG_KASAN_VMALLOC                              342 CONFIG_KASAN_VMALLOC
343 ~~~~~~~~~~~~~~~~~~~~                              343 ~~~~~~~~~~~~~~~~~~~~
344                                                   344 
345 使用 ``CONFIG_KASAN_VMALLOC`` ,KASAN可以    345 使用 ``CONFIG_KASAN_VMALLOC`` ,KASAN可以以更大的內存使用爲代價覆蓋vmalloc
346 空間。目前,這在arm64、x86、riscv、    346 空間。目前,這在arm64、x86、riscv、s390和powerpc上受支持。
347                                                   347 
348 這通過連接到vmalloc和vmap並動態分    348 這通過連接到vmalloc和vmap並動態分配真實的影子內存來支持映射。
349                                                   349 
350 vmalloc空間中的大多數映射都很小,    350 vmalloc空間中的大多數映射都很小,需要不到一整頁的陰影空間。因此,爲每個映射
351 分配一個完整的影子頁面將是一種    351 分配一個完整的影子頁面將是一種浪費。此外,爲了確保不同的映射使用不同的影子
352 頁面,映射必須與 ``KASAN_GRANULE_SIZE     352 頁面,映射必須與 ``KASAN_GRANULE_SIZE * PAGE_SIZE`` 對齊。
353                                                   353 
354 相反,KASAN跨多個映射共享後備空    354 相反,KASAN跨多個映射共享後備空間。當vmalloc空間中的映射使用影子區域的特定
355 頁面時,它會分配一個後備頁面。    355 頁面時,它會分配一個後備頁面。此頁面稍後可以由其他vmalloc映射共享。
356                                                   356 
357 KASAN連接到vmap基礎架構以懶清理未    357 KASAN連接到vmap基礎架構以懶清理未使用的影子內存。
358                                                   358 
359 爲了避免交換映射的困難,KASAN預    359 爲了避免交換映射的困難,KASAN預測覆蓋vmalloc空間的陰影區域部分將不會被早期
360 的陰影頁面覆蓋,但是將不會被映    360 的陰影頁面覆蓋,但是將不會被映射。這將需要更改特定於arch的代碼。
361                                                   361 
362 這允許在x86上支持 ``VMAP_STACK`` ,並    362 這允許在x86上支持 ``VMAP_STACK`` ,並且可以簡化對沒有固定模塊區域的架構的支持。
363                                                   363 
364 對於開發者                                   364 對於開發者
365 ----------                                        365 ----------
366                                                   366 
367 忽略訪問                                      367 忽略訪問
368 ~~~~~~~~                                          368 ~~~~~~~~
369                                                   369 
370 軟件KASAN模式使用編譯器插樁來插    370 軟件KASAN模式使用編譯器插樁來插入有效性檢查。此類檢測可能與內核的某些部分
371 不兼容,因此需要禁用。                 371 不兼容,因此需要禁用。
372                                                   372 
373 內核的其他部分可能會訪問已分配    373 內核的其他部分可能會訪問已分配對象的元數據。通常,KASAN會檢測並報告此類訪問,
374 但在某些情況下(例如,在內存分    374 但在某些情況下(例如,在內存分配器中),這些訪問是有效的。
375                                                   375 
376 對於軟件KASAN模式,要禁用特定文    376 對於軟件KASAN模式,要禁用特定文件或目錄的檢測,請將 ``KASAN_SANITIZE`` 添加
377 到相應的內核Makefile中:                    377 到相應的內核Makefile中:
378                                                   378 
379 - 對於單個文件(例如,main.o)::           379 - 對於單個文件(例如,main.o)::
380                                                   380 
381     KASAN_SANITIZE_main.o := n                    381     KASAN_SANITIZE_main.o := n
382                                                   382 
383 - 對於一個目錄下的所有文件::          383 - 對於一個目錄下的所有文件::
384                                                   384 
385     KASAN_SANITIZE := n                           385     KASAN_SANITIZE := n
386                                                   386 
387 對於軟件KASAN模式,要在每個函數    387 對於軟件KASAN模式,要在每個函數的基礎上禁用檢測,請使用KASAN特定的
388 ``__no_sanitize_address`` 函數屬性或通    388 ``__no_sanitize_address`` 函數屬性或通用的 ``noinstr`` 。
389                                                   389 
390 請注意,禁用編譯器插樁(基於每    390 請注意,禁用編譯器插樁(基於每個文件或每個函數)會使KASAN忽略在軟件KASAN模式
391 的代碼中直接發生的訪問。當訪問    391 的代碼中直接發生的訪問。當訪問是間接發生的(通過調用檢測函數)或使用沒有編譯器
392 插樁的基於硬件標籤的模式時,它    392 插樁的基於硬件標籤的模式時,它沒有幫助。
393                                                   393 
394 對於軟件KASAN模式,要在當前任務    394 對於軟件KASAN模式,要在當前任務的一部分內核代碼中禁用KASAN報告,請使用
395 ``kasan_disable_current()``/``kasan_enable_cur    395 ``kasan_disable_current()``/``kasan_enable_current()`` 部分註釋這部分代碼。
396 這也會禁用通過函數調用發生的間    396 這也會禁用通過函數調用發生的間接訪問的報告。
397                                                   397 
398 對於基於標籤的KASAN模式,要禁用    398 對於基於標籤的KASAN模式,要禁用訪問檢查,請使用 ``kasan_reset_tag()`` 或
399 ``page_kasan_tag_reset()`` 。請注意,通    399 ``page_kasan_tag_reset()`` 。請注意,通過 ``page_kasan_tag_reset()``
400 臨時禁用訪問檢查需要通過 ``page_ka    400 臨時禁用訪問檢查需要通過 ``page_kasan_tag`` / ``page_kasan_tag_set`` 保
401 存和恢復每頁KASAN標籤。                  401 存和恢復每頁KASAN標籤。
402                                                   402 
403 測試                                            403 測試
404 ~~~~                                              404 ~~~~
405                                                   405 
406 有一些KASAN測試可以驗證KASAN是否正    406 有一些KASAN測試可以驗證KASAN是否正常工作並可以檢測某些類型的內存損壞。
407 測試由兩部分組成:                         407 測試由兩部分組成:
408                                                   408 
409 1. 與KUnit測試框架集成的測試。使    409 1. 與KUnit測試框架集成的測試。使用 ``CONFIG_KASAN_KUNIT_TEST`` 啓用。
410 這些測試可以通過幾種不同的方式    410 這些測試可以通過幾種不同的方式自動運行和部分驗證;請參閱下面的說明。
411                                                   411 
412 2. 與KUnit不兼容的測試。使用 ``CONFI    412 2. 與KUnit不兼容的測試。使用 ``CONFIG_KASAN_MODULE_TEST`` 啓用並且只能作爲模塊
413 運行。這些測試只能通過加載內核    413 運行。這些測試只能通過加載內核模塊並檢查內核日誌以獲取KASAN報告來手動驗證。
414                                                   414 
415 如果檢測到錯誤,每個KUnit兼容的KA    415 如果檢測到錯誤,每個KUnit兼容的KASAN測試都會打印多個KASAN報告之一,然後測試打印
416 其編號和狀態。                             416 其編號和狀態。
417                                                   417 
418 當測試通過::                                 418 當測試通過::
419                                                   419 
420         ok 28 - kmalloc_double_kzfree             420         ok 28 - kmalloc_double_kzfree
421                                                   421 
422 當由於 ``kmalloc`` 失敗而導致測試失    422 當由於 ``kmalloc`` 失敗而導致測試失敗時::
423                                                   423 
424         # kmalloc_large_oob_right: ASSERTION F    424         # kmalloc_large_oob_right: ASSERTION FAILED at mm/kasan/kasan_test.c:245
425         Expected ptr is not null, but is          425         Expected ptr is not null, but is
426         not ok 5 - kmalloc_large_oob_right        426         not ok 5 - kmalloc_large_oob_right
427                                                   427 
428 當由於缺少KASAN報告而導致測試失    428 當由於缺少KASAN報告而導致測試失敗時::
429                                                   429 
430         # kmalloc_double_kzfree: EXPECTATION F    430         # kmalloc_double_kzfree: EXPECTATION FAILED at mm/kasan/kasan_test.c:709
431         KASAN failure expected in "kfree_sensi    431         KASAN failure expected in "kfree_sensitive(ptr)", but none occurred
432         not ok 28 - kmalloc_double_kzfree         432         not ok 28 - kmalloc_double_kzfree
433                                                   433 
434                                                   434 
435 最後打印所有KASAN測試的累積狀態    435 最後打印所有KASAN測試的累積狀態。成功::
436                                                   436 
437         ok 1 - kasan                              437         ok 1 - kasan
438                                                   438 
439 或者,如果其中一項測試失敗::         439 或者,如果其中一項測試失敗::
440                                                   440 
441         not ok 1 - kasan                          441         not ok 1 - kasan
442                                                   442 
443 有幾種方法可以運行與KUnit兼容的KA    443 有幾種方法可以運行與KUnit兼容的KASAN測試。
444                                                   444 
445 1. 可加載模塊                                445 1. 可加載模塊
446                                                   446 
447    啓用 ``CONFIG_KUNIT`` 後,KASAN-KUnit    447    啓用 ``CONFIG_KUNIT`` 後,KASAN-KUnit測試可以構建爲可加載模塊,並通過使用
448    ``insmod`` 或 ``modprobe`` 加載 ``kasan_    448    ``insmod`` 或 ``modprobe`` 加載 ``kasan_test.ko`` 來運行。
449                                                   449 
450 2. 內置                                         450 2. 內置
451                                                   451 
452    通過內置 ``CONFIG_KUNIT`` ,也可以    452    通過內置 ``CONFIG_KUNIT`` ,也可以內置KASAN-KUnit測試。在這種情況下,
453    測試將在啓動時作爲後期初始化    453    測試將在啓動時作爲後期初始化調用運行。
454                                                   454 
455 3. 使用kunit_tool                               455 3. 使用kunit_tool
456                                                   456 
457    通過內置 ``CONFIG_KUNIT`` 和 ``CONFIG_    457    通過內置 ``CONFIG_KUNIT`` 和 ``CONFIG_KASAN_KUNIT_TEST`` ,還可以使用
458    ``kunit_tool`` 以更易讀的方式查看K    458    ``kunit_tool`` 以更易讀的方式查看KUnit測試結果。這不會打印通過測試
459    的KASAN報告。有關 ``kunit_tool`` 更    459    的KASAN報告。有關 ``kunit_tool`` 更多最新信息,請參閱
460    `KUnit文檔 <https://www.kernel.org/doc/ht    460    `KUnit文檔 <https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html>`_ 。
461                                                   461 
462 .. _KUnit: https://www.kernel.org/doc/html/lat    462 .. _KUnit: https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.html
463                                                   463 
                                                      

~ [ 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