asan 的原理
概述
如何判定进程能否访问一片内存区域?一个直观的想法是: 给每个字节做个记号(poison state),将进程不能够访问的字节标记为 poisoned,然后在每次访问内存之前先检查它的 poison state,如果是 poisoned,那么就可以判断发生了非法访问。asan 的核心算法就是基于这个想法,asan 会使用一片专门的内存来保存 application memory 每个字节的 poison state,这片内存的专业名称是 shallow memory,在访问地址 addr 之前,首先在 shadow memory 中检查 addr 的 poison state,如果 poison state 是 poisoned,那么就可以判定发生了非法访问,asan 会及时报告错误,否则程序正常运行。
实际上,asan 的实现远比上面描述的要复杂, 概括地说,asan 由两部分组成:
| 组成部分 | 功能 | |
| instrumentation module (检查模块) |
在开启了 asan 后,在编译时,instrumentation module 会对程序做如下转换: 一、将每个内存访问按照上面描述的方式进行转换 二、在 stack object 和 global object 周围创建"poisoned redzones"以检测 undeflow和overflow 错误 |
编译时 |
| run-time library (运行时库) |
在开启了 asan 后,编译器会让程序动态链接 asan run-time library,它的作用: 一、实现了一个专用的 memory allocator: 1、将 malloc,free 等动态内存管理相关的函数替换为 asan 的特殊实现 2、在 heap object 周围创建"poisoned redzones"以检测 undeflow 和 overflow 3、延迟对释放的 heap 内存的重用以检测 use-after-free 类错误 二、实现报错功能 |
运行时 |
通过上述内容可以看出:asan 的实现既依赖于 compiler 在编译时对源代码做特殊的转换(由 instrumentation module 实现),还依赖一个运行时库,下文将对上述内容进行更加详细的介绍。
Shadow Memory
asan 会将进程的 memory space 分为两大类:
-
Application Memory(简称为 Mem)
这部分内存属于应用进程,由应用进程进行使用。
-
Shadow Memory(简称为 Shadow)
这部分内存用于存放 shadow value,shadow value 其实就是 Mem 各个 byte 的 poison state。”Shadow“的字面意思是“影子”,在 asan 的具体实现上,Mem 和 Shadow 之间存在着一一对应的关系,这就相当于现实生活中的"影子"。按照 Mem 和 Shadow 之间的一一对应的关系,将 Mem 中的一个 byte 标记为“poisoned”是通过将这个 byte 对应的 Shadow 中的 byte 设置为特殊值来实现的。
Shadow memory 是内存错误检查工具中普遍采用的一种技术,在使用这种技术时,会涉及如下两个问题:
-
Application Memory to Shadow Memory mapping (MemToShadow),即如何将 Application Memory 中的每个字节映射到 Shadow Memory 中。
在 asan 的具体实现中, 这两类内存的组织方式、映射方式应使计算 Application Memory 对应的 Shadow Memory 的速度快 。
-
Shadow encoding,即 Shadow Memory 如何紧凑地保存 Application Memory 的 poison state。
<

asan是一种内存错误检测工具,通过在程序编译时插入检查代码并在运行时维护内存访问状态来检测内存错误。它使用shadow memory记录每片内存的访问状态,并在访问内存前检查其状态。此外,asan还在内存对象周围创建poisoned red zones来检测溢出错误。
最低0.47元/天 解锁文章
67

被折叠的 条评论
为什么被折叠?



