AddressSanitizer, что означают эти термины? - PullRequest
0 голосов
/ 01 марта 2020

Итак, я использую AddressSanitizer. Но при описании проблемы используются некоторые плотные термины.

Shadow bytes around the buggy address:
  0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  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 00 00 00 00[fa]fa 00 00 00 fa fa fa 00 00
  0x0c067fff8010: 00 fa fa fa fa fa fa 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
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==7320==ABORTING

Что означает Heap left redzone? (и другие, но меня больше всего интересует fa, так как есть один [fa], который, вероятно, указывает на проблему?)

1 Ответ

2 голосов
/ 02 марта 2020

Что означает левая красная зона Heap?

Когда промежуточный распределитель кучи AddressSanitizer выделяет память кучи в ответ на что-то вроде:

char *p = malloc(5);

он выделяет больше памяти, чем вы попросил о. Допустим, он выделяет 32 байта по адресу q. Затем он пометит первые 16 байтов (регион [q, q+15]) как недоступную кучу в левой красной зоне (fa), следующие 5 байтов как адресуемую (0), а следующие 11 байтов как кучу правой красной зоны (fb).

Наконец, он вернет q+16 приложению (назначенному p).

Теперь, если приложение пытается прочитать или записать из p-1, p-2, ... p-15, все такие попытки будут обнаружены, потому что все они окажутся в левой красной зоне. Это переполнение кучи.

Аналогично, попытки доступа к p+5, p+6, ... p+10 (переполнение кучи) будут обнаружены, поскольку все они окажутся в правой красной зоне.

Зачем приложению когда-либо иметь переполнение кучи? Рассмотрим следующий код:

int idx = get_valid_index(...);  // return -1 on failure
...
if (p[idx] == ...) {   // BUG: forgot to check idx!=-1

На самом деле это происходит чаще, чем вы думаете, и кажется, что это случилось с вами.

...