Поделиться через


Ошибка: heap-use-after-free

Ошибка санитизатора адресов: использование освобожденной памяти

Мы показываем три примера, в которых хранилище в куче можно выделить через malloc, realloc (C) и new (C++), а также ошибочное использование volatile.

Примере- malloc

// example1.cpp
// heap-use-after-free error
#include <stdlib.h>

int main() {
  char *x = (char*)malloc(10 * sizeof(char));
  free(x);

  // ...

  return x[5];   // Boom!
}

Чтобы создать и проверить этот пример, выполните следующие команды в командной строке разработчика Visual Studio 2019 версии 16.9 или более поздней:

cl example1.cpp /fsanitize=address /Zi
devenv /debugexe example1.exe

Когда появится Visual Studio, нажмите F5 , чтобы запустить пример 1.

Результирующая ошибка

Screenshot of the debugger displaying use of deallocated memory error for example 1.

Исключение, вызываемое диалоговым окном, указывает на строку 11, возвращать x [ 5], а также говорит: "Ошибка sanitizer Address Error Use of deallocated memory". Не показан на снимке экрана выходные данные в окне консоли, в котором показаны адреса памяти, а также ключ для идентификации адресируемых байтов, частично адресируемых байтов, освобожденных областей кучи и кучи слева от красной зоны в области ошибки.

Примере- operator new

// example2.cpp
// heap-use-after-free error
#include <windows.h>

int main() {
  char *buffer = new char[42];
  delete [] buffer;

  // ...

  buffer[0] = 42;  // Boom!
  return 0;
}

Чтобы создать и проверить этот пример, выполните следующие команды в командной строке разработчика Visual Studio 2019 версии 16.9 или более поздней:

cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe

Когда появится Visual Studio, нажмите, F5 чтобы запустить пример 2.

Результирующая ошибка — новый оператор

Screenshot of the debugger displaying use of deallocated memory error in example 2.

Исключение, вызываемое диалоговым окном, указывает на строку 11, буфер[0] = 42 и говорит: Ошибка санитизатора адресов: использование освобожденной памяти. Не показан на снимке экрана выходные данные в окне консоли, в котором показаны адреса памяти, а также ключ для определения адресных байтов, частично адресируемых байтов, освобожденных кучи областей и кучи слева от красной зоны в области ошибки.

Примере- realloc

// example3.cpp
// heap-use-after-free error
#include <malloc.h>

int main() {
  char *buffer = (char*)realloc(0, 42);
  free(buffer);

  // ...

  buffer[0] = 42;  // Boom!
  return 0;
}

Чтобы создать и проверить этот пример, выполните следующие команды в командной строке разработчика Visual Studio 2019 версии 16.9 или более поздней:

cl example3.cpp /fsanitize=address /Zi
devenv /debugexe example3.exe

Когда появится Visual Studio, нажмите, F5 чтобы запустить пример 3.

Результирующая ошибка — realloc

Screenshot of the debugger displaying use of deallocated memory error in example 3.

Исключение, вызываемое диалоговым окном, указывает на строку 11, буфер[0] = 42 и говорит: Ошибка санитизатора адресов: использование освобожденной памяти. Не показан на снимке экрана выходные данные в окне консоли, в котором показаны адреса памяти, а также ключ для идентификации адресируемых байтов, частично адресируемых байтов, освобожденных областей кучи и кучи слева от красной зоны в области ошибки.

Пример — переменная

// example4.cpp
// heap-use-after-free error
#include <stdlib.h>

int main() {

  volatile char *x = (char*)malloc(sizeof(char));
  free((void*)x);

      //...

  *x = 42;        // Boom!
}

Чтобы создать и проверить этот пример, выполните следующие команды в командной строке разработчика Visual Studio 2019 версии 16.9 или более поздней:

cl example4.cpp /fsanitize=address /Zi
devenv /debugexe example4.exe

Когда появится Visual Studio, нажмите, F5 чтобы запустить пример 4.

Результирующая ошибка — переменная

Screenshot of the debugger displaying a use of deallocated memory error in example 4.

Исключение, вызываемое диалоговым окном, указывает на строку 12, *x = 42 и говорит: Ошибка санитизатора адресов: использование освобожденной памяти. Не показан на снимке экрана выходные данные в окне консоли, в котором показаны адреса памяти, а также ключ для идентификации адресных байтов, кучи слева от красной зоны и некоторых адресируемых и частично адресируемых байтов в области ошибки.

См. также

Обзор AddressSanitizer
Известные проблемы AddressSanitizer
Справочник по сборке и языку AddressSanitizer
Справочник по среде выполнения AddressSanitizer
Теневой байт AddressSanitizer
Облачное или распределенное тестирование AddressSanitizer
Интеграция отладчика AddressSanitizer
Примеры ошибок AddressSanitizer