往期知识点记录:
基本概念
LMS全称为Lite Memory Sanitizer,是一种实时检测内存操作合法性的调测工具。LMS能够实时检测缓冲区溢出(buffer overflow),释放后使用(use after free) 和重复释放(double free), 在异常发生的第一时间通知操作系统,结合backtrace等定位手段,能准确定位到产生内存问题的代码行,极大提升内存问题定位效率。
OpenHarmony LiteOS-A内核的LMS模块提供下面几种功能:
-
支持多内存池检测;
-
支持LOS_MemAlloc、LOS_MemAllocAlign、LOS_MemRealloc申请出的内存检测;
-
支持安全函数的访问检测(默认开启);
-
支持libc 高频函数的访问检测,包括:memset、memcpy、memmove、strcat、strcpy、strncat、strncpy。
运行机制
LMS使用影子内存映射标记系统内存的状态,一共可标记为三个状态:可读写,不可读写,已释放。影子内存存放在内存池的尾部。
-
内存从堆上申请后,会将数据区的影子内存设置为“可读写”状态,并将头节点区的影子内存设置为“不可读写”状态。
-
内存在堆上被释放时,会将被释放内存的影子内存设置为“已释放”状态。
-
编译代码时,会在代码中的读写指令前插入检测函数,对地址的合法性进行检验。主要是检测访问内存的影子内存的状态值,若检测到影子内存为不可读写,则会报溢出错误;若检测到影子内存为已释放,则会报释放后使用错误。
-
在内存释放时,会检测被释放地址的影子内存状态值,若检测到影子内存非可读写,则会报重复释放错误。
接口说明
内核态
OpenHarmony LiteOS-A内核的LMS模块提供下面几种功能,接口详细信息可以查看 API 参考。
表1 LMS模块接口说明
功能分类 | 接口名 | 描述 |
---|---|---|
添加指定内存池被检测 | LOS_LmsCheckPoolAdd | 将指定内存池的地址范围添加到LMS的内存检测链表上,当访问的地址在链表范围内时,LMS才进行合法性校验;且LOS_MemInit接口会调用该接口,默认将初始化的内存池挂入到检测链表中。 |
删除指定内存池不被检测 | LOS_LmsCheckPoolDel | 不检测指定内存池地址范围内的合法性校验。 |
使能指定内存段锁保护 | LOS_LmsAddrProtect | 为某段内存地址上锁,设置为不可读写,一旦访问则报错。 |
去能指定内存段锁保护 | LOS_LmsAddrDisableProtect | 为某段内存地址解锁,设置为可读写。 |
用户态
用户态仅提供LMS检测库,不提供对外接口。
开发指导
内核态开发流程
开启LMS调测的典型流程如下:
-
配置LMS模块相关宏。 配置LMS控制宏LOSCFG_KERNEL_LMS,默认关,在kernel/liteos_a目录下执行 make update_config命令配置"Kernel->Enable Lite Memory Sanitizer"中打开YES:
宏 menuconfig选项 含义 取值 LOSCFG_KERNEL_LMS Enable Lms Feature Lms模块的裁剪开关 YES/NO LOSCFG_LMS_MA