应该如何阅读堆缓冲区溢出错误消息?

How should the heap-buffer-overflow error message be read?

我想知道应该如何阅读以下错误消息。特别是:

(1) fa(heap left redzone)和fd(freed heap region)是什么意思?

(2)00和05的意义是什么。

(3)被指向的内存块(0x0c067fff8010)有什么意义?

(4)什么是野指针?

(5)为什么fa在方括号([fa])中有指向它的箭头的内存块所在的那一行?

编译命令

clang++ test.cpp -fsanitize=address -D_LIBCPP_DEBUG=1

错误信息

Address 0x6030000000f0 is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow 
(/home/tzadiko/randomStuff/a.out+0x4fa83d) in main
Shadow bytes around the buggy address:
  0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c067fff8000: fa fa fd fd fd fd fa fa 00 00 00 07 fa fa 00 00
=>0x0c067fff8010: 05 fa fa fa 00 00 04 fa fa fa fa fa fa fa[fa]fa
  0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

您遗漏了输出的关键部分。这是图例(摘自 the documentation):

Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe

看完this description,我想你的问题地址依次是:

  1. redzone 是分配的左侧和右侧的不可访问数据区域。 ASan 保留整个内存的位掩码,并确定每个 8 字节区域的内存类型。

  2. 如图例所示,00 是完全可寻址的内存,01 到 07 表示 "partially addressable"。其中带有 05 的值大概意味着可以寻址该 8 字节块的前 5 个字节。

  3. 0x0c067fff801e 是位图中的索引。括号中的部分表示预期的影子字节。将它乘以 8 得到 0x6033fffc00f0,大概还必须对其进行一些修改才能返回到有问题的内存区域。

  4. 野指针是指向未分配(或最近释放)内存的指针。

  5. 见3.