概述
Kernel Address SANitizer(KASAN)是一种动态内存安全错误检测工具,主要功能是 检查内存越界访问和使用已释放内存的问题。
KASAN有三种模式:
通用KASAN
基于软件标签的KASAN
基于硬件标签的KASAN
用CONFIG_KASAN_GENERIC启用的通用KASAN,是用于调试的模式,类似于用户空 间的ASan。这种模式在许多CPU架构上都被支持,但它有明显的性能和内存开销。
基于软件标签的KASAN或SW_TAGS KASAN,通过CONFIG_KASAN_SW_TAGS启用, 可以用于调试和自我测试,类似于用户空间HWASan。这种模式只支持arm64,但其 适度的内存开销允许在内存受限的设备上用真实的工作负载进行测试。
基于硬件标签的KASAN或HW_TAGS KASAN,用CONFIG_KASAN_HW_TAGS启用,被 用作现场内存错误检测器或作为安全缓解的模式。这种模式只在支持MTE(内存标签 扩展)的arm64 CPU上工作,但它的内存和性能开销很低,因此可以在生产中使用。
关于每种KASAN模式的内存和性能影响的细节,请参见相应的Kconfig选项的描述。
通用模式和基于软件标签的模式通常被称为软件模式。基于软件标签的模式和基于 硬件标签的模式被称为基于标签的模式。
支持
体系架构
在x86_64、arm、arm64、powerpc、riscv、s390、xtensa和loongarch上支持通用KASAN, 而基于标签的KASAN模式只在arm64上支持。
编译器
软件KASAN模式使用编译时工具在每个内存访问之前插入有效性检查,因此需要一个 提供支持的编译器版本。基于硬件标签的模式依靠硬件来执行这些检查,但仍然需要 一个支持内存标签指令的编译器版本。
通用KASAN需要GCC 8.3.0版本或更高版本,或者内核支持的任何Clang版本。
基于软件标签的KASAN需要GCC 11+或者内核支持的任何Clang版本。
基于硬件标签的KASAN需要GCC 10+或Clang 12+。
内存类型
通用KASAN支持在所有的slab、page_alloc、vmap、vmalloc、堆栈和全局内存 中查找错误。
基于软件标签的KASAN支持slab、page_alloc、vmalloc和堆栈内存。
基于硬件标签的KASAN支持slab、page_alloc和不可执行的vmalloc内存。
对于slab,两种软件KASAN模式都支持SLUB和SLAB分配器,而基于硬件标签的 KASAN只支持SLUB。
用法
要启用KASAN,请使用以下命令配置内核:
CONFIG_KASAN=y
同时在 CONFIG_KASAN_GENERIC (启用通用KASAN模式), CONFIG_KASAN_SW_TAGS (启用基于硬件标签的KASAN模式),和 CONFIG_KASAN_HW_TAGS (启用基于硬件标签 的KASAN模式)之间进行选择。
对于软件模式,还可以在 CONFIG_KASAN_OUTLINE 和 CONFIG_KASAN_INLINE 之间进行选择。outline和inline是编译器插桩类型。前者产生较小的二进制文件, 而后者快2倍。
要将受影响的slab对象的alloc和free堆栈跟踪包含到报告中,请启用 CONFIG_STACKTRACE 。要包括受影响物理页面的分配和释放堆栈跟踪的话, 请启用 CONFIG_PAGE_OWNER 并使用 page_owner=on 进行引导。
启动参数
KASAN受到通用 panic_on_warn 命令行参数的影响。当它被启用时,KASAN 在打印出错误报告后会使内核恐慌。
默认情况下,KASAN只对第一个无效的内存访问打印错误报告。使用 kasan_multi_shot,KASAN对每一个无效的访问都打印一份报告。这会禁用 了KASAN报告的 panic_on_warn。
另外,独立于 panic_on_warn 、 kasan.fault= boot参数可以用 来控制恐慌和报告行为。
kasan.fault=report 或 =panic 控制是否只打印KASAN report或 同时使内核恐慌(默认: report )。即使 kasan_multi_shot 被 启用,恐慌也会发生。
基于软件和硬件标签的KASAN模式(见下面关于各种模式的部分)支持改变堆栈跟 踪收集行为:
kasan.stacktrace=off 或 =on 禁用或启用分配和释放堆栈痕 迹的收集(默认: on )。
kasan.stack_ring_size= 指定堆栈环的条 目数(默认: 32768 )。
基于硬件标签的KASAN模式是为了在生产中作为一种安全缓解措施使用。因此,它 支持额外的启动参数,允许完全禁用KASAN或控制其功能。
kasan=off 或 =on 控制KASAN是否被启用(默认: on )。
kasan.mode=sync, =async o