sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/dev-tools/kasanmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/zh_TW/dev-tools/kasanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/it_IT/dev-tools/kasanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/ja_JP/dev-tools/kasanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/ko_KR/dev-tools/kasanmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget#/translations/sp_SP/dev-tools/kasanmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhP/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/dev-tools/kasan.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h!Documentation/dev-tools/kasan.rsth]h)}(hhh]h!Documentation/dev-tools/kasan.rst}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h Translatorh]h Translator}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhKubh)}(h,万家兵 Wan Jiabing h]h)}(h+万家兵 Wan Jiabing h](h万家兵 Wan Jiabing <}(hjhhhNhNubh reference)}(hwanjiabing@vivo.comh]hwanjiabing@vivo.com}(hj)hhhNhNubah}(h]h ]h"]h$]h&]refurimailto:wanjiabing@vivo.comuh1j'hjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhj ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(h内核地址消毒剂(KASAN)h]h内核地址消毒剂(KASAN)}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjWhhhhhK ubjV)}(hhh](j[)}(h概述h]h概述}(hjmhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjjhhhhhK ubh)}(hKernel Address SANitizer(KASAN)是一种动态内存安全错误检测工具,主要功能是 检查内存越界访问和使用已释放内存的问题。h]hKernel Address SANitizer(KASAN)是一种动态内存安全错误检测工具,主要功能是 检查内存越界访问和使用已释放内存的问题。}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjhhubh)}(hKASAN有三种模式:h]hKASAN有三种模式:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjhhubhenumerated_list)}(hhh](h list_item)}(h 通用KASANh]h)}(hjh]h 通用KASAN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h基于软件标签的KASANh]h)}(hjh]h基于软件标签的KASAN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(h基于硬件标签的KASAN h]h)}(h基于硬件标签的KASANh]h基于硬件标签的KASAN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1jhjjhhhhhKubh)}(h用CONFIG_KASAN_GENERIC启用的通用KASAN,是用于调试的模式,类似于用户空 间的ASan。这种模式在许多CPU架构上都被支持,但它有明显的性能和内存开销。h]h用CONFIG_KASAN_GENERIC启用的通用KASAN,是用于调试的模式,类似于用户空 间的ASan。这种模式在许多CPU架构上都被支持,但它有明显的性能和内存开销。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjhhubh)}(hX基于软件标签的KASAN或SW_TAGS KASAN,通过CONFIG_KASAN_SW_TAGS启用, 可以用于调试和自我测试,类似于用户空间HWASan。这种模式只支持arm64,但其 适度的内存开销允许在内存受限的设备上用真实的工作负载进行测试。h]hX基于软件标签的KASAN或SW_TAGS KASAN,通过CONFIG_KASAN_SW_TAGS启用, 可以用于调试和自我测试,类似于用户空间HWASan。这种模式只支持arm64,但其 适度的内存开销允许在内存受限的设备上用真实的工作负载进行测试。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjhhubh)}(hX'基于硬件标签的KASAN或HW_TAGS KASAN,用CONFIG_KASAN_HW_TAGS启用,被 用作现场内存错误检测器或作为安全缓解的模式。这种模式只在支持MTE(内存标签 扩展)的arm64 CPU上工作,但它的内存和性能开销很低,因此可以在生产中使用。h]hX'基于硬件标签的KASAN或HW_TAGS KASAN,用CONFIG_KASAN_HW_TAGS启用,被 用作现场内存错误检测器或作为安全缓解的模式。这种模式只在支持MTE(内存标签 扩展)的arm64 CPU上工作,但它的内存和性能开销很低,因此可以在生产中使用。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjjhhubh)}(hf关于每种KASAN模式的内存和性能影响的细节,请参见相应的Kconfig选项的描述。h]hf关于每种KASAN模式的内存和性能影响的细节,请参见相应的Kconfig选项的描述。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK"hjjhhubh)}(h通用模式和基于软件标签的模式通常被称为软件模式。基于软件标签的模式和基于 硬件标签的模式被称为基于标签的模式。h]h通用模式和基于软件标签的模式通常被称为软件模式。基于软件标签的模式和基于 硬件标签的模式被称为基于标签的模式。}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hjjhhubeh}(h]id1ah ]h"]概述ah$]h&]uh1jUhjWhhhhhK ubjV)}(hhh](j[)}(h支持h]h支持}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj=hhhhhK(ubjV)}(hhh](j[)}(h 体系架构h]h 体系架构}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjNhhhhhK+ubh)}(h在x86_64、arm、arm64、powerpc、riscv、s390、xtensa和loongarch上支持通用KASAN, 而基于标签的KASAN模式只在arm64上支持。h]h在x86_64、arm、arm64、powerpc、riscv、s390、xtensa和loongarch上支持通用KASAN, 而基于标签的KASAN模式只在arm64上支持。}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK-hjNhhubeh}(h]id3ah ]h"] 体系架构ah$]h&]uh1jUhj=hhhhhK+ubjV)}(hhh](j[)}(h 编译器h]h 编译器}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjuhhhhhK1ubh)}(hX软件KASAN模式使用编译时工具在每个内存访问之前插入有效性检查,因此需要一个 提供支持的编译器版本。基于硬件标签的模式依靠硬件来执行这些检查,但仍然需要 一个支持内存标签指令的编译器版本。h]hX软件KASAN模式使用编译时工具在每个内存访问之前插入有效性检查,因此需要一个 提供支持的编译器版本。基于硬件标签的模式依靠硬件来执行这些检查,但仍然需要 一个支持内存标签指令的编译器版本。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK3hjuhhubh)}(h[通用KASAN需要GCC 8.3.0版本或更高版本,或者内核支持的任何Clang版本。h]h[通用KASAN需要GCC 8.3.0版本或更高版本,或者内核支持的任何Clang版本。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK7hjuhhubh)}(hP基于软件标签的KASAN需要GCC 11+或者内核支持的任何Clang版本。h]hP基于软件标签的KASAN需要GCC 11+或者内核支持的任何Clang版本。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK9hjuhhubh)}(h6基于硬件标签的KASAN需要GCC 10+或Clang 12+。h]h6基于硬件标签的KASAN需要GCC 10+或Clang 12+。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK;hjuhhubeh}(h]id4ah ]h"] 编译器ah$]h&]uh1jUhj=hhhhhK1ubjV)}(hhh](j[)}(h 内存类型h]h 内存类型}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhK>ubh)}(hj通用KASAN支持在所有的slab、page_alloc、vmap、vmalloc、堆栈和全局内存 中查找错误。h]hj通用KASAN支持在所有的slab、page_alloc、vmap、vmalloc、堆栈和全局内存 中查找错误。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK@hjhhubh)}(hM基于软件标签的KASAN支持slab、page_alloc、vmalloc和堆栈内存。h]hM基于软件标签的KASAN支持slab、page_alloc、vmalloc和堆栈内存。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjhhubh)}(hS基于硬件标签的KASAN支持slab、page_alloc和不可执行的vmalloc内存。h]hS基于硬件标签的KASAN支持slab、page_alloc和不可执行的vmalloc内存。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEhjhhubh)}(hr对于slab,两种软件KASAN模式都支持SLUB和SLAB分配器,而基于硬件标签的 KASAN只支持SLUB。h]hr对于slab,两种软件KASAN模式都支持SLUB和SLAB分配器,而基于硬件标签的 KASAN只支持SLUB。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKGhjhhubeh}(h]id5ah ]h"] 内存类型ah$]h&]uh1jUhj=hhhhhK>ubeh}(h]id2ah ]h"]支持ah$]h&]uh1jUhjWhhhhhK(ubjV)}(hhh](j[)}(h用法h]h用法}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhKKubh)}(h4要启用KASAN,请使用以下命令配置内核::h]h3要启用KASAN,请使用以下命令配置内核:}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKMhjhhubh literal_block)}(hCONFIG_KASAN=yh]hCONFIG_KASAN=y}hj@sbah}(h]h ]h"]h$]h&]hhuh1j>hhhKOhjhhubh)}(h同时在 ``CONFIG_KASAN_GENERIC`` (启用通用KASAN模式), ``CONFIG_KASAN_SW_TAGS`` (启用基于硬件标签的KASAN模式),和 ``CONFIG_KASAN_HW_TAGS`` (启用基于硬件标签 的KASAN模式)之间进行选择。h](h 同时在 }(hjNhhhNhNubhliteral)}(h``CONFIG_KASAN_GENERIC``h]hCONFIG_KASAN_GENERIC}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjNubh (启用通用KASAN模式), }(hjNhhhNhNubjW)}(h``CONFIG_KASAN_SW_TAGS``h]hCONFIG_KASAN_SW_TAGS}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjNubh0 (启用基于硬件标签的KASAN模式),和 }(hjNhhhNhNubjW)}(h``CONFIG_KASAN_HW_TAGS``h]hCONFIG_KASAN_HW_TAGS}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjNubh? (启用基于硬件标签 的KASAN模式)之间进行选择。}(hjNhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKQhjhhubh)}(h对于软件模式,还可以在 ``CONFIG_KASAN_OUTLINE`` 和 ``CONFIG_KASAN_INLINE`` 之间进行选择。outline和inline是编译器插桩类型。前者产生较小的二进制文件, 而后者快2倍。h](h"对于软件模式,还可以在 }(hjhhhNhNubjW)}(h``CONFIG_KASAN_OUTLINE``h]hCONFIG_KASAN_OUTLINE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh 和 }(hjhhhNhNubjW)}(h``CONFIG_KASAN_INLINE``h]hCONFIG_KASAN_INLINE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh| 之间进行选择。outline和inline是编译器插桩类型。前者产生较小的二进制文件, 而后者快2倍。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKUhjhhubh)}(hX要将受影响的slab对象的alloc和free堆栈跟踪包含到报告中,请启用 ``CONFIG_STACKTRACE`` 。要包括受影响物理页面的分配和释放堆栈跟踪的话, 请启用 ``CONFIG_PAGE_OWNER`` 并使用 ``page_owner=on`` 进行引导。h](hV要将受影响的slab对象的alloc和free堆栈跟踪包含到报告中,请启用 }(hjhhhNhNubjW)}(h``CONFIG_STACKTRACE``h]hCONFIG_STACKTRACE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubhT 。要包括受影响物理页面的分配和释放堆栈跟踪的话, 请启用 }(hjhhhNhNubjW)}(h``CONFIG_PAGE_OWNER``h]hCONFIG_PAGE_OWNER}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh 并使用 }(hjhhhNhNubjW)}(h``page_owner=on``h]h page_owner=on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh 进行引导。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKYhjhhubjV)}(hhh](j[)}(h 启动参数h]h 启动参数}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj hhhhhK^ubh)}(hKASAN受到通用 ``panic_on_warn`` 命令行参数的影响。当它被启用时,KASAN 在打印出错误报告后会使内核恐慌。h](hKASAN受到通用 }(hjhhhNhNubjW)}(h``panic_on_warn``h]h panic_on_warn}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubhg 命令行参数的影响。当它被启用时,KASAN 在打印出错误报告后会使内核恐慌。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK`hj hhubh)}(h默认情况下,KASAN只对第一个无效的内存访问打印错误报告。使用 ``kasan_multi_shot``,KASAN对每一个无效的访问都打印一份报告。这会禁用 了KASAN报告的 ``panic_on_warn``。h](hW默认情况下,KASAN只对第一个无效的内存访问打印错误报告。使用 }(hj;hhhNhNubjW)}(h``kasan_multi_shot``h]hkasan_multi_shot}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj;ubhZ,KASAN对每一个无效的访问都打印一份报告。这会禁用 了KASAN报告的 }(hj;hhhNhNubjW)}(h``panic_on_warn``h]h panic_on_warn}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj;ubh。}(hj;hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKchj hhubh)}(ho另外,独立于 ``panic_on_warn`` 、 ``kasan.fault=`` boot参数可以用 来控制恐慌和报告行为。h](h另外,独立于 }(hjmhhhNhNubjW)}(h``panic_on_warn``h]h panic_on_warn}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjmubh 、 }(hjmhhhNhNubjW)}(h``kasan.fault=``h]h kasan.fault=}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjmubh6 boot参数可以用 来控制恐慌和报告行为。}(hjmhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKghj hhubh bullet_list)}(hhh]j)}(h``kasan.fault=report`` 或 ``=panic`` 控制是否只打印KASAN report或 同时使内核恐慌(默认: ``report`` )。即使 ``kasan_multi_shot`` 被 启用,恐慌也会发生。 h]h)}(h``kasan.fault=report`` 或 ``=panic`` 控制是否只打印KASAN report或 同时使内核恐慌(默认: ``report`` )。即使 ``kasan_multi_shot`` 被 启用,恐慌也会发生。h](jW)}(h``kasan.fault=report``h]hkasan.fault=report}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh 或 }(hjhhhNhNubjW)}(h ``=panic``h]h=panic}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubhH 控制是否只打印KASAN report或 同时使内核恐慌(默认: }(hjhhhNhNubjW)}(h ``report``h]hreport}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh )。即使 }(hjhhhNhNubjW)}(h``kasan_multi_shot``h]hkasan_multi_shot}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh# 被 启用,恐慌也会发生。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKjhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubah}(h]h ]h"]h$]h&]bullet-uh1jhhhKjhj hhubh)}(h{基于软件和硬件标签的KASAN模式(见下面关于各种模式的部分)支持改变堆栈跟 踪收集行为:h]h{基于软件和硬件标签的KASAN模式(见下面关于各种模式的部分)支持改变堆栈跟 踪收集行为:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKnhj hhubj)}(hhh](j)}(ht``kasan.stacktrace=off`` 或 ``=on`` 禁用或启用分配和释放堆栈痕 迹的收集(默认: ``on`` )。 h]h)}(hs``kasan.stacktrace=off`` 或 ``=on`` 禁用或启用分配和释放堆栈痕 迹的收集(默认: ``on`` )。h](jW)}(h``kasan.stacktrace=off``h]hkasan.stacktrace=off}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh 或 }(hjhhhNhNubjW)}(h``=on``h]h=on}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubhB 禁用或启用分配和释放堆栈痕 迹的收集(默认: }(hjhhhNhNubjW)}(h``on``h]hon}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh )。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKqhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hh``kasan.stack_ring_size=`` 指定堆栈环的条 目数(默认: ``32768`` )。 h]h)}(hg``kasan.stack_ring_size=`` 指定堆栈环的条 目数(默认: ``32768`` )。h](jW)}(h-``kasan.stack_ring_size=``h]h)kasan.stack_ring_size=}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjgubh* 指定堆栈环的条 目数(默认: }(hjghhhNhNubjW)}(h ``32768``h]h32768}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjgubh )。}(hjghhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKthjcubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhKqhj hhubh)}(h基于硬件标签的KASAN模式是为了在生产中作为一种安全缓解措施使用。因此,它 支持额外的启动参数,允许完全禁用KASAN或控制其功能。h]h基于硬件标签的KASAN模式是为了在生产中作为一种安全缓解措施使用。因此,它 支持额外的启动参数,允许完全禁用KASAN或控制其功能。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhj hhubj)}(hhh](j)}(hO``kasan=off`` 或 ``=on`` 控制KASAN是否被启用(默认: ``on`` )。 h]h)}(hN``kasan=off`` 或 ``=on`` 控制KASAN是否被启用(默认: ``on`` )。h](jW)}(h ``kasan=off``h]h kasan=off}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh 或 }(hjhhhNhNubjW)}(h``=on``h]h=on}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh( 控制KASAN是否被启用(默认: }(hjhhhNhNubjW)}(h``on``h]hon}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh )。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKzhjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(hX.``kasan.mode=sync``, ``=async`` or ``=asymm`` 控制KASAN是否 被配置为同步、异步或非对称的执行模式(默认: ``同步`` )。 同步模式:当标签检查异常发生时,会立即检测到不良访问。 异步模式:不良访问的检测是延迟的。当标签检查异常发生时,信息被存储在硬 件中(对于arm64来说是在TFSR_EL1寄存器中)。内核周期性地检查硬件,并\ 且只在这些检查中报告标签异常。 非对称模式:读取时同步检测不良访问,写入时异步检测。 h]h)}(hX-``kasan.mode=sync``, ``=async`` or ``=asymm`` 控制KASAN是否 被配置为同步、异步或非对称的执行模式(默认: ``同步`` )。 同步模式:当标签检查异常发生时,会立即检测到不良访问。 异步模式:不良访问的检测是延迟的。当标签检查异常发生时,信息被存储在硬 件中(对于arm64来说是在TFSR_EL1寄存器中)。内核周期性地检查硬件,并\ 且只在这些检查中报告标签异常。 非对称模式:读取时同步检测不良访问,写入时异步检测。h](jW)}(h``kasan.mode=sync``h]hkasan.mode=sync}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh, }(hjhhhNhNubjW)}(h ``=async``h]h=async}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh or }(hjhhhNhNubjW)}(h ``=asymm``h]h=asymm}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubhV 控制KASAN是否 被配置为同步、异步或非对称的执行模式(默认: }(hjhhhNhNubjW)}(h ``同步``h]h同步}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubhX )。 同步模式:当标签检查异常发生时,会立即检测到不良访问。 异步模式:不良访问的检测是延迟的。当标签检查异常发生时,信息被存储在硬 件中(对于arm64来说是在TFSR_EL1寄存器中)。内核周期性地检查硬件,并 且只在这些检查中报告标签异常。 非对称模式:读取时同步检测不良访问,写入时异步检测。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK|hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubj)}(ha``kasan.vmalloc=off`` or ``=on`` 禁用或启用vmalloc分配的标记(默认: ``on`` )。 h]h)}(h```kasan.vmalloc=off`` or ``=on`` 禁用或启用vmalloc分配的标记(默认: ``on`` )。h](jW)}(h``kasan.vmalloc=off``h]hkasan.vmalloc=off}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj\ubh or }(hj\hhhNhNubjW)}(h``=on``h]h=on}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj\ubh3 禁用或启用vmalloc分配的标记(默认: }(hj\hhhNhNubjW)}(h``on``h]hon}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj\ubh )。}(hj\hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjXubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhKzhj hhubeh}(h]id7ah ]h"] 启动参数ah$]h&]uh1jUhjhhhhhK^ubjV)}(hhh](j[)}(h 错误报告h]h 错误报告}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhKubh)}(h"典型的KASAN报告如下所示::h]h!典型的KASAN报告如下所示:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj?)}(hXO ================================================================== 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 ==================================================================h]hXO ================================================================== 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 ==================================================================}hjsbah}(h]h ]h"]h$]h&]hhuh1j>hhhKhjhhubh)}(hX报告标题总结了发生的错误类型以及导致该错误的访问类型。紧随其后的是错误访问的 堆栈跟踪、所访问内存分配位置的堆栈跟踪(对于访问了slab对象的情况)以及对象 被释放的位置的堆栈跟踪(对于访问已释放内存的问题报告)。接下来是对访问的 slab对象的描述以及关于访问的内存页的信息。h]hX报告标题总结了发生的错误类型以及导致该错误的访问类型。紧随其后的是错误访问的 堆栈跟踪、所访问内存分配位置的堆栈跟踪(对于访问了slab对象的情况)以及对象 被释放的位置的堆栈跟踪(对于访问已释放内存的问题报告)。接下来是对访问的 slab对象的描述以及关于访问的内存页的信息。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX 最后,报告展示了访问地址周围的内存状态。在内部,KASAN单独跟踪每个内存颗粒的 内存状态,根据KASAN模式分为8或16个对齐字节。报告的内存状态部分中的每个数字 都显示了围绕访问地址的其中一个内存颗粒的状态。h]hX 最后,报告展示了访问地址周围的内存状态。在内部,KASAN单独跟踪每个内存颗粒的 内存状态,根据KASAN模式分为8或16个对齐字节。报告的内存状态部分中的每个数字 都显示了围绕访问地址的其中一个内存颗粒的状态。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX[对于通用KASAN,每个内存颗粒的大小为8个字节。每个颗粒的状态被编码在一个影子字节 中。这8个字节可以是可访问的,部分访问的,已释放的或成为Redzone的一部分。KASAN 对每个影子字节使用以下编码:00表示对应内存区域的所有8个字节都可以访问;数字N (1 <= N <= 7)表示前N个字节可访问,其他(8 - N)个字节不可访问;任何负值都表示 无法访问整个8字节。KASAN使用不同的负值来区分不同类型的不可访问内存,如redzones 或已释放的内存(参见 mm/kasan/kasan.h)。h]hX[对于通用KASAN,每个内存颗粒的大小为8个字节。每个颗粒的状态被编码在一个影子字节 中。这8个字节可以是可访问的,部分访问的,已释放的或成为Redzone的一部分。KASAN 对每个影子字节使用以下编码:00表示对应内存区域的所有8个字节都可以访问;数字N (1 <= N <= 7)表示前N个字节可访问,其他(8 - N)个字节不可访问;任何负值都表示 无法访问整个8字节。KASAN使用不同的负值来区分不同类型的不可访问内存,如redzones 或已释放的内存(参见 mm/kasan/kasan.h)。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hh在上面的报告中,箭头指向影子字节 ``03`` ,表示访问的地址是部分可访问的。h](h1在上面的报告中,箭头指向影子字节 }(hjhhhNhNubjW)}(h``03``h]h03}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh1 ,表示访问的地址是部分可访问的。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h对于基于标签的KASAN模式,报告最后的部分显示了访问地址周围的内存标签 (参考 `实施细则`_ 章节)。h](hk对于基于标签的KASAN模式,报告最后的部分显示了访问地址周围的内存标签 (参考 }(hj'hhhNhNubj()}(h`实施细则`_h]h 实施细则}(hj/hhhNhNubah}(h]h ]h"]h$]h&]name 实施细则refidid9uh1j'hj'resolvedKubh 章节)。}(hj'hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h请注意,KASAN错误标题(如 ``slab-out-of-bounds`` 或 ``use-after-free`` ) 是尽量接近的:KASAN根据其拥有的有限信息打印出最可能的错误类型。错误的实际类型 可能会有所不同。h](h$请注意,KASAN错误标题(如 }(hjLhhhNhNubjW)}(h``slab-out-of-bounds``h]hslab-out-of-bounds}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjLubh 或 }(hjLhhhNhNubjW)}(h``use-after-free``h]huse-after-free}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjLubh ) 是尽量接近的:KASAN根据其拥有的有限信息打印出最可能的错误类型。错误的实际类型 可能会有所不同。}(hjLhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h通用KASAN还报告两个辅助调用堆栈跟踪。这些堆栈跟踪指向代码中与对象交互但不直接 出现在错误访问堆栈跟踪中的位置。目前,这包括 call_rcu() 和排队的工作队列。h]h通用KASAN还报告两个辅助调用堆栈跟踪。这些堆栈跟踪指向代码中与对象交互但不直接 出现在错误访问堆栈跟踪中的位置。目前,这包括 call_rcu() 和排队的工作队列。}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id8ah ]h"] 错误报告ah$]h&]uh1jUhjhhhhhKubjV)}(hhh](j[)}(hCONFIG_KASAN_EXTRA_INFOh]hCONFIG_KASAN_EXTRA_INFO}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhKubh)}(hX启用 CONFIG_KASAN_EXTRA_INFO 选项允许 KASAN 记录和报告更多信息。目前支持的 额外信息包括分配和释放时的 CPU 编号和时间戳。更多的信息可以帮助找到内核错误的原因, 并将错误与其他系统事件关联起来,但代价是用额外的内存来记录更多信息(有关更多 开销的细节,请参见 CONFIG_KASAN_EXTRA_INFO 选项的帮助文本)。h]hX启用 CONFIG_KASAN_EXTRA_INFO 选项允许 KASAN 记录和报告更多信息。目前支持的 额外信息包括分配和释放时的 CPU 编号和时间戳。更多的信息可以帮助找到内核错误的原因, 并将错误与其他系统事件关联起来,但代价是用额外的内存来记录更多信息(有关更多 开销的细节,请参见 CONFIG_KASAN_EXTRA_INFO 选项的帮助文本)。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hQ以下为 CONFIG_KASAN_EXTRA_INFO 开启后的报告(仅显示不同部分)::h]hP以下为 CONFIG_KASAN_EXTRA_INFO 开启后的报告(仅显示不同部分):}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj?)}(h================================================================== ... Allocated by task 134 on cpu 5 at 229.133855s: ... Freed by task 136 on cpu 3 at 230.199335s: ... ==================================================================h]h================================================================== ... Allocated by task 134 on cpu 5 at 229.133855s: ... Freed by task 136 on cpu 3 at 230.199335s: ... ==================================================================}hjsbah}(h]h ]h"]h$]h&]hhuh1j>hhhKhjhhubeh}(h]config-kasan-extra-infoah ]h"]config_kasan_extra_infoah$]h&]uh1jUhjhhhhhKubeh}(h]id6ah ]h"]用法ah$]h&]uh1jUhjWhhhhhKKubjV)}(hhh](j[)}(h 实施细则h]h 实施细则}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhMubjV)}(hhh](j[)}(h 通用KASANh]h 通用KASAN}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhMubh)}(h软件KASAN模式使用影子内存来记录每个内存字节是否可以安全访问,并使用编译时工具 在每次内存访问之前插入影子内存检查。h]h软件KASAN模式使用影子内存来记录每个内存字节是否可以安全访问,并使用编译时工具 在每次内存访问之前插入影子内存检查。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h通用KASAN将1/8的内核内存专用于其影子内存(16TB以覆盖x86_64上的128TB),并使用 具有比例和偏移量的直接映射将内存地址转换为其相应的影子地址。h]h通用KASAN将1/8的内核内存专用于其影子内存(16TB以覆盖x86_64上的128TB),并使用 具有比例和偏移量的直接映射将内存地址转换为其相应的影子地址。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjhhubh)}(h8这是将地址转换为其相应影子地址的函数::h]h7这是将地址转换为其相应影子地址的函数:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjhhubj?)}(hstatic inline void *kasan_mem_to_shadow(const void *addr) { return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET; }h]hstatic inline void *kasan_mem_to_shadow(const void *addr) { return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET; }}hj+sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhjhhubh)}(h.在这里 ``KASAN_SHADOW_SCALE_SHIFT = 3`` 。h](h 在这里 }(hj9hhhNhNubjW)}(h ``KASAN_SHADOW_SCALE_SHIFT = 3``h]hKASAN_SHADOW_SCALE_SHIFT = 3}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj9ubh 。}(hj9hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hX 编译时工具用于插入内存访问检查。编译器在每次访问大小为1、2、4、8或16的内存之前 插入函数调用( ``__asan_load*(addr)`` , ``__asan_store*(addr)``)。这些函数通过 检查相应的影子内存来检查内存访问是否有效。h](h编译时工具用于插入内存访问检查。编译器在每次访问大小为1、2、4、8或16的内存之前 插入函数调用( }(hjYhhhNhNubjW)}(h``__asan_load*(addr)``h]h__asan_load*(addr)}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjYubh , }(hjYhhhNhNubjW)}(h``__asan_store*(addr)``h]h__asan_store*(addr)}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjYubhV)。这些函数通过 检查相应的影子内存来检查内存访问是否有效。}(hjYhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h使用inline插桩,编译器不进行函数调用,而是直接插入代码来检查影子内存。此选项 显著地增大了内核体积,但与outline插桩内核相比,它提供了x1.1-x2的性能提升。h]h使用inline插桩,编译器不进行函数调用,而是直接插入代码来检查影子内存。此选项 显著地增大了内核体积,但与outline插桩内核相比,它提供了x1.1-x2的性能提升。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h通用KASAN是唯一一种通过隔离延迟重新使用已释放对象的模式 (参见 mm/kasan/quarantine.c 以了解实现)。h]h通用KASAN是唯一一种通过隔离延迟重新使用已释放对象的模式 (参见 mm/kasan/quarantine.c 以了解实现)。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]id10ah ]h"] 通用kasanah$]h&]uh1jUhjhhhhhMubjV)}(hhh](j[)}(h 基于软件标签的KASAN模式h]h 基于软件标签的KASAN模式}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjhhhhhM!ubh)}(hv基于软件标签的KASAN使用软件内存标签方法来检查访问有效性。目前仅针对arm64架构实现。h]hv基于软件标签的KASAN使用软件内存标签方法来检查访问有效性。目前仅针对arm64架构实现。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM#hjhhubh)}(hX基于软件标签的KASAN使用arm64 CPU的顶部字节忽略(TBI)特性在内核指针的顶部字节中 存储一个指针标签。它使用影子内存来存储与每个16字节内存单元相关的内存标签(因此, 它将内核内存的1/16专用于影子内存)。h]hX基于软件标签的KASAN使用arm64 CPU的顶部字节忽略(TBI)特性在内核指针的顶部字节中 存储一个指针标签。它使用影子内存来存储与每个16字节内存单元相关的内存标签(因此, 它将内核内存的1/16专用于影子内存)。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hjhhubh)}(h在每次内存分配时,基于软件标签的KASAN都会生成一个随机标签,用这个标签标记分配 的内存,并将相同的标签嵌入到返回的指针中。h]h在每次内存分配时,基于软件标签的KASAN都会生成一个随机标签,用这个标签标记分配 的内存,并将相同的标签嵌入到返回的指针中。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM)hjhhubh)}(hX基于软件标签的KASAN使用编译时工具在每次内存访问之前插入检查。这些检查确保正在 访问的内存的标签等于用于访问该内存的指针的标签。如果标签不匹配,基于软件标签 的KASAN会打印错误报告。h]hX基于软件标签的KASAN使用编译时工具在每次内存访问之前插入检查。这些检查确保正在 访问的内存的标签等于用于访问该内存的指针的标签。如果标签不匹配,基于软件标签 的KASAN会打印错误报告。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM,hjhhubh)}(hX`基于软件标签的KASAN也有两种插桩模式(outline,发出回调来检查内存访问;inline, 执行内联的影子内存检查)。使用outline插桩模式,会从执行访问检查的函数打印错误 报告。使用inline插桩,编译器会发出 ``brk`` 指令,并使用专用的 ``brk`` 处理程序 来打印错误报告。h](hX基于软件标签的KASAN也有两种插桩模式(outline,发出回调来检查内存访问;inline, 执行内联的影子内存检查)。使用outline插桩模式,会从执行访问检查的函数打印错误 报告。使用inline插桩,编译器会发出 }(hjhhhNhNubjW)}(h``brk``h]hbrk}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh 指令,并使用专用的 }(hjhhhNhNubjW)}(h``brk``h]hbrk}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjubh& 处理程序 来打印错误报告。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM0hjhhubh)}(h基于软件标签的KASAN使用0xFF作为匹配所有指针标签(不检查通过带有0xFF指针标签 的指针进行的访问)。值0xFE当前保留用于标记已释放的内存区域。h]h基于软件标签的KASAN使用0xFF作为匹配所有指针标签(不检查通过带有0xFF指针标签 的指针进行的访问)。值0xFE当前保留用于标记已释放的内存区域。}(hj* hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM5hjhhubeh}(h]id11ah ]h"] 基于软件标签的kasan模式ah$]h&]uh1jUhjhhhhhM!ubjV)}(hhh](j[)}(h 基于硬件标签的KASAN模式h]h 基于硬件标签的KASAN模式}(hjC hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj@ hhhhhM:ubh)}(h基于硬件标签的KASAN在概念上类似于软件模式,但它是使用硬件内存标签作为支持而 不是编译器插桩和影子内存。h]h基于硬件标签的KASAN在概念上类似于软件模式,但它是使用硬件内存标签作为支持而 不是编译器插桩和影子内存。}(hjQ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM<hj@ hhubh)}(h基于硬件标签的KASAN目前仅针对arm64架构实现,并且基于ARMv8.5指令集架构中引入 的arm64内存标记扩展(MTE)和最高字节忽略(TBI)。h]h基于硬件标签的KASAN目前仅针对arm64架构实现,并且基于ARMv8.5指令集架构中引入 的arm64内存标记扩展(MTE)和最高字节忽略(TBI)。}(hj_ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM?hj@ hhubh)}(hX0特殊的arm64指令用于为每次内存分配指定内存标签。相同的标签被指定给指向这些分配 的指针。在每次内存访问时,硬件确保正在访问的内存的标签等于用于访问该内存的指针 的标签。如果标签不匹配,则会生成故障并打印报告。h]hX0特殊的arm64指令用于为每次内存分配指定内存标签。相同的标签被指定给指向这些分配 的指针。在每次内存访问时,硬件确保正在访问的内存的标签等于用于访问该内存的指针 的标签。如果标签不匹配,则会生成故障并打印报告。}(hjm hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMBhj@ hhubh)}(h基于硬件标签的KASAN使用0xFF作为匹配所有指针标签(不检查通过带有0xFF指针标签的 指针进行的访问)。值0xFE当前保留用于标记已释放的内存区域。h]h基于硬件标签的KASAN使用0xFF作为匹配所有指针标签(不检查通过带有0xFF指针标签的 指针进行的访问)。值0xFE当前保留用于标记已释放的内存区域。}(hj{ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMFhj@ hhubh)}(h如果硬件不支持MTE(ARMv8.5之前),则不会启用基于硬件标签的KASAN。在这种情况下, 所有KASAN引导参数都将被忽略。h]h如果硬件不支持MTE(ARMv8.5之前),则不会启用基于硬件标签的KASAN。在这种情况下, 所有KASAN引导参数都将被忽略。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMIhj@ hhubh)}(h请注意,启用CONFIG_KASAN_HW_TAGS始终会导致启用内核中的TBI。即使提供了 ``kasan.mode=off`` 或硬件不支持MTE(但支持TBI)。h](h]请注意,启用CONFIG_KASAN_HW_TAGS始终会导致启用内核中的TBI。即使提供了 }(hj hhhNhNubjW)}(h``kasan.mode=off``h]hkasan.mode=off}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh+ 或硬件不支持MTE(但支持TBI)。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMLhj@ hhubh)}(he基于硬件标签的KASAN只报告第一个发现的错误。之后,MTE标签检查将被禁用。h]he基于硬件标签的KASAN只报告第一个发现的错误。之后,MTE标签检查将被禁用。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMOhj@ hhubeh}(h]id12ah ]h"] 基于硬件标签的kasan模式ah$]h&]uh1jUhjhhhhhM:ubeh}(h]j@ah ]h"] 实施细则ah$]h&]uh1jUhjWhhhhhM referencedKubjV)}(hhh](j[)}(h 影子内存h]h 影子内存}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj hhhhhMRubh)}(h/本节的内容只适用于软件KASAN模式。h]h/本节的内容只适用于软件KASAN模式。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMThj hhubh)}(hX内核将内存映射到地址空间的几个不同部分。内核虚拟地址的范围很大:没有足够的真实 内存来支持内核可以访问的每个地址的真实影子区域。因此,KASAN只为地址空间的某些 部分映射真实的影子。h]hX内核将内存映射到地址空间的几个不同部分。内核虚拟地址的范围很大:没有足够的真实 内存来支持内核可以访问的每个地址的真实影子区域。因此,KASAN只为地址空间的某些 部分映射真实的影子。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMVhj hhubjV)}(hhh](j[)}(h 默认行为h]h 默认行为}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj hhhhhM[ubh)}(hX=默认情况下,体系结构仅将实际内存映射到用于线性映射的阴影区域(以及可能的其他 小区域)。对于所有其他区域 —— 例如vmalloc和vmemmap空间 —— 一个只读页面被映射 到阴影区域上。这个只读的影子页面声明所有内存访问都是允许的。h]hX=默认情况下,体系结构仅将实际内存映射到用于线性映射的阴影区域(以及可能的其他 小区域)。对于所有其他区域 —— 例如vmalloc和vmemmap空间 —— 一个只读页面被映射 到阴影区域上。这个只读的影子页面声明所有内存访问都是允许的。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM]hj hhubh)}(hX 这给模块带来了一个问题:它们不存在于线性映射中,而是存在于专用的模块空间中。 通过连接模块分配器,KASAN临时映射真实的影子内存以覆盖它们。例如,这允许检测 对模块全局变量的无效访问。h]hX 这给模块带来了一个问题:它们不存在于线性映射中,而是存在于专用的模块空间中。 通过连接模块分配器,KASAN临时映射真实的影子内存以覆盖它们。例如,这允许检测 对模块全局变量的无效访问。}(hj! hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMahj hhubh)}(h这也造成了与 ``VMAP_STACK`` 的不兼容:如果堆栈位于vmalloc空间中,它将被分配 只读页面的影子内存,并且内核在尝试为堆栈变量设置影子数据时会出错。h](h这也造成了与 }(hj/ hhhNhNubjW)}(h``VMAP_STACK``h]h VMAP_STACK}(hj7 hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj/ ubh 的不兼容:如果堆栈位于vmalloc空间中,它将被分配 只读页面的影子内存,并且内核在尝试为堆栈变量设置影子数据时会出错。}(hj/ hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMehj hhubeh}(h]id14ah ]h"] 默认行为ah$]h&]uh1jUhj hhhhhM[ubjV)}(hhh](j[)}(hCONFIG_KASAN_VMALLOCh]hCONFIG_KASAN_VMALLOC}(hjZ hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhjW hhhhhMiubh)}(h使用 ``CONFIG_KASAN_VMALLOC`` ,KASAN可以以更大的内存使用为代价覆盖vmalloc 空间。目前,这在arm64、x86、riscv、s390和powerpc上受支持。h](h使用 }(hjh hhhNhNubjW)}(h``CONFIG_KASAN_VMALLOC``h]hCONFIG_KASAN_VMALLOC}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjh ubh ,KASAN可以以更大的内存使用为代价覆盖vmalloc 空间。目前,这在arm64、x86、riscv、s390和powerpc上受支持。}(hjh hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMkhjW hhubh)}(hV这通过连接到vmalloc和vmap并动态分配真实的影子内存来支持映射。h]hV这通过连接到vmalloc和vmap并动态分配真实的影子内存来支持映射。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMnhjW hhubh)}(hX#vmalloc空间中的大多数映射都很小,需要不到一整页的阴影空间。因此,为每个映射 分配一个完整的影子页面将是一种浪费。此外,为了确保不同的映射使用不同的影子 页面,映射必须与 ``KASAN_GRANULE_SIZE * PAGE_SIZE`` 对齐。h](hvmalloc空间中的大多数映射都很小,需要不到一整页的阴影空间。因此,为每个映射 分配一个完整的影子页面将是一种浪费。此外,为了确保不同的映射使用不同的影子 页面,映射必须与 }(hj hhhNhNubjW)}(h"``KASAN_GRANULE_SIZE * PAGE_SIZE``h]hKASAN_GRANULE_SIZE * PAGE_SIZE}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh 对齐。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMphjW hhubh)}(h相反,KASAN跨多个映射共享后备空间。当vmalloc空间中的映射使用影子区域的特定 页面时,它会分配一个后备页面。此页面稍后可以由其他vmalloc映射共享。h]h相反,KASAN跨多个映射共享后备空间。当vmalloc空间中的映射使用影子区域的特定 页面时,它会分配一个后备页面。此页面稍后可以由其他vmalloc映射共享。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMthjW hhubh)}(hEKASAN连接到vmap基础架构以懒清理未使用的影子内存。h]hEKASAN连接到vmap基础架构以懒清理未使用的影子内存。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMwhjW hhubh)}(h为了避免交换映射的困难,KASAN预测覆盖vmalloc空间的阴影区域部分将不会被早期 的阴影页面覆盖,但是将不会被映射。这将需要更改特定于arch的代码。h]h为了避免交换映射的困难,KASAN预测覆盖vmalloc空间的阴影区域部分将不会被早期 的阴影页面覆盖,但是将不会被映射。这将需要更改特定于arch的代码。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMyhjW hhubh)}(hm这允许在x86上支持 ``VMAP_STACK`` ,并且可以简化对没有固定模块区域的架构的支持。h](h这允许在x86上支持 }(hj hhhNhNubjW)}(h``VMAP_STACK``h]h VMAP_STACK}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubhF ,并且可以简化对没有固定模块区域的架构的支持。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM|hjW hhubeh}(h]config-kasan-vmallocah ]h"]config_kasan_vmallocah$]h&]uh1jUhj hhhhhMiubeh}(h]id13ah ]h"] 影子内存ah$]h&]uh1jUhjWhhhhhMRubjV)}(hhh](j[)}(h对于开发者h]h对于开发者}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj hhhhhMubjV)}(hhh](j[)}(h 忽略访问h]h 忽略访问}(hj$ hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj! hhhhhMubh)}(h软件KASAN模式使用编译器插桩来插入有效性检查。此类检测可能与内核的某些部分 不兼容,因此需要禁用。h]h软件KASAN模式使用编译器插桩来插入有效性检查。此类检测可能与内核的某些部分 不兼容,因此需要禁用。}(hj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj! hhubh)}(h内核的其他部分可能会访问已分配对象的元数据。通常,KASAN会检测并报告此类访问, 但在某些情况下(例如,在内存分配器中),这些访问是有效的。h]h内核的其他部分可能会访问已分配对象的元数据。通常,KASAN会检测并报告此类访问, 但在某些情况下(例如,在内存分配器中),这些访问是有效的。}(hj@ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj! hhubh)}(h对于软件KASAN模式,要禁用特定文件或目录的检测,请将 ``KASAN_SANITIZE`` 添加 到相应的内核Makefile中:h](hK对于软件KASAN模式,要禁用特定文件或目录的检测,请将 }(hjN hhhNhNubjW)}(h``KASAN_SANITIZE``h]hKASAN_SANITIZE}(hjV hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjN ubh& 添加 到相应的内核Makefile中:}(hjN hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj! hhubj)}(hhh](j)}(hD对于单个文件(例如,main.o):: KASAN_SANITIZE_main.o := n h](h)}(h%对于单个文件(例如,main.o)::h]h$对于单个文件(例如,main.o):}(hju hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjq ubj?)}(hKASAN_SANITIZE_main.o := nh]hKASAN_SANITIZE_main.o := n}hj sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhjq ubeh}(h]h ]h"]h$]h&]uh1jhjn hhhhhNubj)}(h>对于一个目录下的所有文件:: KASAN_SANITIZE := n h](h)}(h&对于一个目录下的所有文件::h]h%对于一个目录下的所有文件:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubj?)}(hKASAN_SANITIZE := nh]hKASAN_SANITIZE := n}hj sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhj ubeh}(h]h ]h"]h$]h&]uh1jhjn hhhhhNubeh}(h]h ]h"]h$]h&]jjuh1jhhhMhj! hhubh)}(h对于软件KASAN模式,要在每个函数的基础上禁用检测,请使用KASAN特定的 ``__no_sanitize_address`` 函数属性或通用的 ``noinstr`` 。h](h_对于软件KASAN模式,要在每个函数的基础上禁用检测,请使用KASAN特定的 }(hj hhhNhNubjW)}(h``__no_sanitize_address``h]h__no_sanitize_address}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh 函数属性或通用的 }(hj hhhNhNubjW)}(h ``noinstr``h]hnoinstr}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh 。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj! hhubh)}(hX 请注意,禁用编译器插桩(基于每个文件或每个函数)会使KASAN忽略在软件KASAN模式 的代码中直接发生的访问。当访问是间接发生的(通过调用检测函数)或使用没有编译器 插桩的基于硬件标签的模式时,它没有帮助。h]hX 请注意,禁用编译器插桩(基于每个文件或每个函数)会使KASAN忽略在软件KASAN模式 的代码中直接发生的访问。当访问是间接发生的(通过调用检测函数)或使用没有编译器 插桩的基于硬件标签的模式时,它没有帮助。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj! hhubh)}(h对于软件KASAN模式,要在当前任务的一部分内核代码中禁用KASAN报告,请使用 ``kasan_disable_current()``/``kasan_enable_current()`` 部分注释这部分代码。 这也会禁用通过函数调用发生的间接访问的报告。h](he对于软件KASAN模式,要在当前任务的一部分内核代码中禁用KASAN报告,请使用 }(hj hhhNhNubjW)}(h``kasan_disable_current()``h]hkasan_disable_current()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh/}(hj hhhNhNubjW)}(h``kasan_enable_current()``h]hkasan_enable_current()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubhb 部分注释这部分代码。 这也会禁用通过函数调用发生的间接访问的报告。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj! hhubh)}(hX 对于基于标签的KASAN模式,要禁用访问检查,请使用 ``kasan_reset_tag()`` 或 ``page_kasan_tag_reset()`` 。请注意,通过 ``page_kasan_tag_reset()`` 临时禁用访问检查需要通过 ``page_kasan_tag`` / ``page_kasan_tag_set`` 保 存和恢复每页KASAN标签。h](hE对于基于标签的KASAN模式,要禁用访问检查,请使用 }(hj5 hhhNhNubjW)}(h``kasan_reset_tag()``h]hkasan_reset_tag()}(hj= hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj5 ubh 或 }(hj5 hhhNhNubjW)}(h``page_kasan_tag_reset()``h]hpage_kasan_tag_reset()}(hjO hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj5 ubh 。请注意,通过 }(hj5 hhhNhNubjW)}(h``page_kasan_tag_reset()``h]hpage_kasan_tag_reset()}(hja hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj5 ubh& 临时禁用访问检查需要通过 }(hj5 hhhNhNubjW)}(h``page_kasan_tag``h]hpage_kasan_tag}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj5 ubh / }(hj5 hhhNhNubjW)}(h``page_kasan_tag_set``h]hpage_kasan_tag_set}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj5 ubh% 保 存和恢复每页KASAN标签。}(hj5 hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj! hhubeh}(h]id16ah ]h"] 忽略访问ah$]h&]uh1jUhj hhhhhMubjV)}(hhh](j[)}(h测试h]h测试}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jZhj hhhhhMubh)}(hd有一些KASAN测试可以验证KASAN是否正常工作并可以检测某些类型的内存损坏。h]hd有一些KASAN测试可以验证KASAN是否正常工作并可以检测某些类型的内存损坏。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h所有 KASAN 测试都与 KUnit 测试框架集成,可通过 ``CONFIG_KASAN_KUNIT_TEST`` 启用。 测试可以通过几种不同的方式自动运行和部分验证;请参阅以下说明。h](h?所有 KASAN 测试都与 KUnit 测试框架集成,可通过 }(hj hhhNhNubjW)}(h``CONFIG_KASAN_KUNIT_TEST``h]hCONFIG_KASAN_KUNIT_TEST}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1*jVhj ubhh 启用。 测试可以通过几种不同的方式自动运行和部分验证;请参阅以下说明。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h如果检测到错误,每个 KASAN 测试都会打印多份 KASAN 报告中的一份。 然后测试会打印其编号和状态。h]h如果检测到错误,每个 KASAN 测试都会打印多份 KASAN 报告中的一份。 然后测试会打印其编号和状态。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h当测试通过::h]h当测试通过:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj?)}(hok 28 - kmalloc_double_kzfreeh]hok 28 - kmalloc_double_kzfree}hj sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhj hhubh)}(h6当由于 ``kmalloc`` 失败而导致测试失败时::h](h 当由于 }(hj hhhNhNubjW)}(h ``kmalloc``h]hkmalloc}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh 失败而导致测试失败时:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj?)}(h# 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_righth]h# 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}hj. sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhj hhubh)}(h4当由于缺少KASAN报告而导致测试失败时::h]h3当由于缺少KASAN报告而导致测试失败时:}(hj< hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj?)}(h# 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_kzfreeh]h# 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}hjJ sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhj hhubh)}(h7最后打印所有KASAN测试的累积状态。成功::h]h6最后打印所有KASAN测试的累积状态。成功:}(hjX hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj?)}(h ok 1 - kasanh]h ok 1 - kasan}hjf sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhj hhubh)}(h)或者,如果其中一项测试失败::h]h(或者,如果其中一项测试失败:}(hjt hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj?)}(hnot ok 1 - kasanh]hnot ok 1 - kasan}hj sbah}(h]h ]h"]h$]h&]hhuh1j>hhhMhj hhubh)}(h+有几种方法可以运行 KASAN 测试。h]h+有几种方法可以运行 KASAN 测试。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hhh](j)}(h可加载模块 启用 ``CONFIG_KUNIT`` 后,可以将测试构建为可加载模块 并通过使用 ``insmod`` 或 ``modprobe`` 加载 ``kasan_test.ko`` 来运行。 h](h)}(h可加载模块h]h可加载模块}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(h启用 ``CONFIG_KUNIT`` 后,可以将测试构建为可加载模块 并通过使用 ``insmod`` 或 ``modprobe`` 加载 ``kasan_test.ko`` 来运行。h](h启用 }(hj hhhNhNubjW)}(h``CONFIG_KUNIT``h]h CONFIG_KUNIT}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh? 后,可以将测试构建为可加载模块 并通过使用 }(hj hhhNhNubjW)}(h ``insmod``h]hinsmod}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh 或 }(hj hhhNhNubjW)}(h ``modprobe``h]hmodprobe}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh 加载 }(hj hhhNhNubjW)}(h``kasan_test.ko``h]h kasan_test.ko}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj ubh 来运行。}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubeh}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(h{内置 通过内置 ``CONFIG_KUNIT``,测试也可以内置。 测试将在启动时作为后期初始化调用运行。 h](h)}(h内置h]h内置}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hr通过内置 ``CONFIG_KUNIT``,测试也可以内置。 测试将在启动时作为后期初始化调用运行。h](h 通过内置 }(hj!hhhNhNubjW)}(h``CONFIG_KUNIT``h]h CONFIG_KUNIT}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1jVhj!ubhU,测试也可以内置。 测试将在启动时作为后期初始化调用运行。}(hj!hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1jhj hhhhhNubj)}(hXZ使用kunit_tool 通过内置 ``CONFIG_KUNIT`` 和 ``CONFIG_KASAN_KUNIT_TEST`` ,还可以使用 ``kunit_tool`` 以更易读的方式查看KUnit测试结果。这不会打印通过测试 的KASAN报告。有关 ``kunit_tool`` 更多最新信息,请参阅 `KUnit文档 `_ 。 h](h)}(h使用kunit_toolh]h使用kunit_tool}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjGubh)}(hXG通过内置 ``CONFIG_KUNIT`` 和 ``CONFIG_KASAN_KUNIT_TEST`` ,还可以使用 ``kunit_tool`` 以更易读的方式查看KUnit测试结果。这不会打印通过测试 的KASAN报告。有关 ``kunit_tool`` 更多最新信息,请参阅 `KUnit文档 `_ 。h](h 通过内置 }(hjYhhhNhNubjW)}(h``CONFIG_KUNIT``h]h CONFIG_KUNIT}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjYubh 和 }(hjYhhhNhNubjW)}(h``CONFIG_KASAN_KUNIT_TEST``h]hCONFIG_KASAN_KUNIT_TEST}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjYubh ,还可以使用 }(hjYhhhNhNubjW)}(h``kunit_tool``h]h kunit_tool}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjYubhd 以更易读的方式查看KUnit测试结果。这不会打印通过测试 的KASAN报告。有关 }(hjYhhhNhNubjW)}(h``kunit_tool``h]h kunit_tool}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jVhjYubh 更多最新信息,请参阅 }(hjYhhhNhNubj()}(hR`KUnit文档 `_h]h KUnit文档}(hjhhhNhNubah}(h]h ]h"]h$]h&]name KUnit文档refuriAhttps://www.kernel.org/doc/html/latest/dev-tools/kunit/index.htmluh1j'hjYubhtarget)}(hD h]h}(h]kunitah ]h"] kunit文档ah$]h&]refurijuh1jj KhjYubh 。}(hjYhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjGubeh}(h]h ]h"]h$]h&]uh1jhj hhhhhNubeh}(h]h ]h"]h$]h&]jjjhjjuh1jhj hhhhhMubj)}(hL.. _KUnit: https://www.kernel.org/doc/html/latest/dev-tools/kunit/index.htmlh]h}(h]id18ah ]h"]kunitah$]h&]jAhttps://www.kernel.org/doc/html/latest/dev-tools/kunit/index.htmluh1jhMhj hhhhubeh}(h]id17ah ]h"]测试ah$]h&]uh1jUhj hhhhhMubeh}(h]id15ah ]h"]对于开发者ah$]h&]uh1jUhjWhhhhhMubeh}(h]kasanah ]h"]内核地址消毒剂(kasan)ah$]h&]uh1jUhhhhhhhK ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jZN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj(error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames} 实施细则]j/asrefids}nameids}(jjj:j7jjjrjojjjjjjjjjjjjj j@jjj= j: j j j j jT jQ j j jjj j jjjjjju nametypes}(jj:jjrjjjjjjj jj= j j jT j jj jjjuh}(jjWj7jjjj=jojNjjujjjjjj jjjjj@jjjj: jj j@ j j jQ j j jW jj j j! jj jjjju footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j6KsRparse_messages]transform_messages]hsystem_message)}(hhh]h)}(hhh]h+Hyperlink target "kunit" is not referenced.}hjsbah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineMuh1juba transformerN include_log]4Documentation/translations/zh_CN/dev-tools/kasan.rst(NNNNta decorationNhhub.