美文网首页
C++内存安全检测工具 Sanitize

C++内存安全检测工具 Sanitize

作者: 谭英智 | 来源:发表于2023-01-31 18:28 被阅读0次

AddressSanitizer

AddressSanitizer可以在运行时,检测内存是否发生了内存错误。

例如可以检测以下问题:

  • Use after free
  • Head/Stack/Global buffer overflow
  • Use after return
  • Use after scope
  • Memory leaks

用法如下:

clang++ -O1 -fsanitize=address a.cc ; ./a.out

原理

内存8 bytes对齐

san-8-bytes
  • 所有8字节都是 unpoisoned ,则为0
  • 所有字节都是 poisoned,则为-1
  • 前k个字节为 unpoisoned,则为k

这些值记录在shadow内存中

通过用内存的1/8的内存记录其他字节的内存状态

shadow使用1 byte的内存来标记8 bytes内存的状态

记录shadow使用以下的代码转换

shadow内存填充

原始代码:

void foo() 
{
  char a[8];
  ...
  return;
}

编译后的代码:

void foo() 
{
  char redzone1[32];  // 32-byte aligned
  char a[8];          // 32-byte aligned
  char redzone2[24];
  char redzone3[32];  // 32-byte aligned
  int  *shadow_base = MemToShadow(redzone1);
  shadow_base[0] = 0xffffffff;  // poison redzone1
  shadow_base[1] = 0xffffff00;  // poison redzone2, unpoison 'a'
  shadow_base[2] = 0xffffffff;  // poison redzone3
  ...
  shadow_base[0] = shadow_base[1] = shadow_base[2] = 0; // unpoison all
  return;
}

地址访问

每次访问之前做内存检查

原始代码:

*address = ...;

编译后代码:

if (IsPoisoned(address))
{
    ReportError(address, kAccessSize, kIsWrite);
}
*address = ...;

malloc/free处理

使用自定义的函数替换malloc和free

malloc的buffer前后填充posion,buffer填充unposion

free的buffer填充posion

ThreadSanitizer

ThreadSanitizer 是用来检测死锁和data race的

原理

代码填充

原始代码:

void foo(int* p) {
    *p = 42;
}

编译后的代码:

void foo(int *p) {
 __tsan_func_entry(__builtin_return_address(0));
 __tsan_write4(p);
 *p = 42;
 __tsan_func_exit()
}

shadow内容

8 bytes的内存

  • 16 bits:线程id
  • 42 bits:Epoch
  • 5 bits: access buffer size
  • 1 bit: IsWrite
san-thread-shadow

通过在内存中动态维持这个shadow,来比较内存是否存在发生data race

MemorySanitizer

MemorySanitizer是用来检测是否使用未初始化内存

用法:

 clang -fsanitize=memory a.c -g; ./a.out

原理

shadow

使用bit-2-bit来做shadow,1 代码 poisoned

每次访问内存时,通过获取shadow的状态,来判断是否发生了使用未初始化内粗

UndefinedBehaviorSanitizer

UndefinedBehaviorSanitizer可以用来检测程序是否发生了未定义行为

例如整数溢出

用法:

clang -fsanitize=undefined a.cc -g; ./a.out

提供的选项:

-fsanitize=alignment
-fsanitize=bool
-fsanitize=bounds
-fsanitize=enum
-fsanitize=float-cast-overflow
-fsanitize=float-divide-by-zero
-fsanitize=function
-fsanitize=integer-divide-by-zero
-fsanitize=null
-fsanitize=returns-nonnull-attribute
-fsanitize=shift
-fsanitize=signed-integer-overflow
-fsanitize=unreachable
-fsanitize=unsigned-integer-overflow
-fsanitize=vla-bound
-fsanitize=vptr
-fsanitize=object-size
-fsanitize=return

相关文章

网友评论

      本文标题:C++内存安全检测工具 Sanitize

      本文链接:https://www.haomeiwen.com/subject/lcdbhdtx.html