Poison, redzones and shadows: inside KASAN
5 days ago
- #Memory Sanitizer
- #Kernel Security
- #Linux Development
- Linux内核主要使用C语言编写,这种语言容易产生未定义行为和缓冲区溢出等内存错误,因此需要像KASAN这样的工具进行早期检测。
- KASAN(内核地址消毒器)是一种运行时检查工具,可检测越界访问和释放后使用错误,它需要在构建时进行编译器插装,并使用影子内存进行跟踪。
- 启用KASAN涉及设置CONFIG_KASAN配置项,包含可调参数,如内联与外部插装模式、硬件支持以及内存类型跟踪(例如vmalloc、堆栈)。
- 通过virtme-ng虚拟化环境可以安全测试KASAN,包括加载kasan_test模块以生成包含堆栈跟踪和内存状态信息的详细错误报告。
- KASAN使用影子内存,预留系统内存的1/8来跟踪内核内存状态,其直接映射公式为:shadow_byte = (target_addr >> 3) + KASAN_SHADOW_OFFSET。
- 影子内存的值表示可访问性:0x00表示完全可访问,正值(如0x03)表示部分可访问,负值则标记为不可访问区域。
- 内存分配时会被“解毒”(影子位设置为0),释放时会被“投毒”(标记为KASAN_SLAB_FREE等标签),并通过红色区域捕获溢出错误。
- 编译器插装在内存访问前通过__asan_load8等函数或内联代码添加检查,提供外部(基于调用)或内联(代码扩展)模式选项,这些选项会影响性能和代码大小。
- KASAN还覆盖全局变量、堆栈内存(通过CONFIG_KASAN_STACK配置),并使用隔离区检测释放后使用错误;特定架构变体(如基于标签的版本)可降低开销。