GCC 10.2/11 ASAN栈缓冲区下溢报告特殊影子字节布局成因咨询
ASAN栈左右红区直接相邻的常见场景
你提到的影子字节模式如下:
someaddr => [f1]f1 f3 f3 f3 where f1 is stack left redzone f3 is stack right redzone.
这类栈左红区与栈右红区之间无有效可寻址字节的影子布局,通常出现在以下场景中:
- 零长度栈变量的边界保护场景
C/C++编译器支持的栈上零长度数组(包括显式定义的char arr[0];、以及部分场景下的柔性数组栈用法)没有实际的有效数据存储空间,GCC 10+的ASAN会为这类变量正常分配左右红区,但不会分配可寻址的数据内存,因此会出现0xf1直接和0xf3相邻的影子内存布局,此时对该地址做任意长度的读写都会触发越界报错。 - 栈变量对齐填充的合并红区场景
当两个相邻栈变量的对齐要求导致中间的填充空间刚好匹配ASAN栈红区的最小粒度时,编译器会将这段填充空间同时标记为前一个变量的右红区和后一个变量的左红区,合并后就会出现红区连续相邻的情况。比如前一个栈变量为1字节的char类型,后一个为需要8字节对齐的int类型,中间7字节的填充空间被划分为前后红区后,就会出现0xf3接0xf1的布局,变量顺序反过来时就会出现0xf1接0xf3的情况。 - 已销毁栈帧的残留标记场景
如果报错地址属于已经执行完成、退出的函数栈帧,ASAN不会立刻擦除该栈帧的影子内存标记,仅会将整个栈帧原本的有效数据区域全部重新标记为红区,此时原本的变量红区和被标记为红区的原数据区域连在一起,就会呈现0xf1和0xf3直接相邻的状态,这类情况通常对应*栈释放后使用(Use-after-return)*类内存错误。 - GCC 10/11 ASAN栈插桩的特殊优化场景
GCC 10.2和11版本对小尺寸栈变量的保护逻辑做过优化,当函数内的栈变量总大小小于32字节、且编译器静态判定该变量不会被通过地址访问时,可能会省略变量的实际内存分配,仅保留前后红区标记,此时也会出现红区直接相邻的影子布局。
内容的提问来源于stack exchange,提问作者tdiff
相关产品推荐
相关产品推荐

