当前位置:首页 > 内存 > 正文

linux内核内存管理

  • 内存
  • 2024-06-11 15:57:34
  • 4603

一、一文搞懂Linux内核内存管理中的KASAN实现原理深入探究Linux内核的KASAN内存保护机制:越界检测及实现原理
KernelAddressSanitizer(KASAN)作为内存故障检测卫士,是专门为Linux4.4及以后版本设计的x86_64和arm64架构。对GC4.9.2及更高版本的强力支持,采用内存监控机制影子内存,确保准确捕获越界内存访问。运行时,只需在编译选项中设置CONFIG_SLUB_DEBUG=y和CONFIG_KASAN=y,SLUB_DEBUG将提供额外的调试信息,并可能会增加的大小。
KASAN的基本策略是使用系统1/8的内存空间作为影子内存,并通过编译时插入的加载/存储检查来实时监控每个内存操作。当内存访问尝试超出指定范围时,内置函数__asan_load#size()和__asan_store#size()将引发异常并发出警告。例如,访问8字节内存需要影子内存值为0。任何偏离此规则的操作都会导致错误检查。
ARM64架构下,KASAN区域位于内核空间的VMALLOC区域,支持KASLR。编译器将在每次内存访问之前和之后自动插入检查,以通过__asan_load#size()和__asan_store#size()验证内存地址。例如,编译器创建全局变量构造函数,使得chara[4]变成struct{charoriginal[4];charredzone[60];},红色区域填充规则由​​占用的物理值的剩余部分决定内存和32字节。
关于shadow内存的实际分配,它与内核地址的关系是:Shadow_addr=(kaddr>>3)+KASAN_SHADOW_OFFSE。KASANZone充当虚拟地址,必须通过映射转换为物理地址才能工作。初始化过程在kasan_early_init()和kasan_init()函数中执行,以确保内存映射正确。在分配内存时,例如kmalloc(20),KASAN会将多余的内存标记为不可访问,以防止无意的越界使用。
更具体地说,KASAN使用structkasan_global结构来管理全局变量,例如smc_num1、smc_num2和smc_num3。通过反汇编和,我们发现每个全局变量都有对应的构造函数。例如smc_num1的构造函数地址为ffff200009381df0,初始化过程由__asan_register_globals()执行。
总之,KASAN通过编译器的智能处理,保证了严格的内存访问控制。它包含堆栈分配变量和全局变量的相应边界检查和影子内存初始化。错误日志提供错误的详细信息,如错误标题、任务、错误描述kmalloc_oob_right等,帮助开发者快速定位问题。
在实践中,KASAN在Linux内核版本4.18中运行良好,通过检测越界错误提供强大的内存管理安全性。深入理解KASAN的工作原理对于保证系统稳定性和代码质量至关重要。