heap-use-after-free

具体例1: すでにfree済みのアドレスを操作しようとしてエラー

レポート結果

ログからわかること

・対象のプロセスIDは 37695
・アドレス 0x619000000580 において、heap-use-after-free を検出した
・PCレジスタが 0x00010b5b3aa8, BPレジスタが 0x7ffee46a5a10, SPレジスタが 0x7ffee46a51c0 の状態だった

・スレッドT0(メインスレッドのこと)で発生
・1バイトの書き込みをしようとした時にアドレス0x619000000580が違反した事を検知した
・test61.cpp の 11行目から呼び出された memset で発生(※コンパイラが自動的に memsetの代わりに __asan_memset を呼び出す処理に書き換えていた)
・アドレス 0x619000000580 は、0x619000000580 から始まる 1024バイトの領域の先頭である。
・test61.cppの8行目で スレッドT0によって解放済
・test61.cppの6行目で 以前はスレッドT0によって確保されていた。

【SUMMARY 以降】
・違反になったアドレスより前の領域は確保されていないヒープ領域(fa)
・違反になったアドレス以降は解放済みのヒープ領域(fd)

【ログから推測できる不具合の内容】

・free されたあとにアクセスしないようにシーケンスを制御し忘れている(アドレス変数をNULLに設定忘れとか。フラグ変更忘れとか。)

参考)上記のログを発生させたソースコード

#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
  // ヒープ確保
  char *ptr = (char *) malloc(1024);
  // ヒープ解放
  free(ptr);

  // 解放したアドレスに対する操作
  memset(ptr, 0, 1);

  return 0;
}

参考)コンパイル・実行例

$ clang++ -g -O0 -o test61 -fsanitize=address test61.cpp
$ ./test61

具体例2: すでにdelete済みのアドレスを操作しようとしてエラー

レポート結果

ログからわかること

・対象のプロセスIDは 37872
・アドレス 0x619000000580 において、heap-use-after-free を検出した
・PCレジスタが 0x000101181aa8, BPレジスタが 0x7ffeeead5a00, SPレジスタが 0x7ffeeead51b0 の状態だった

・スレッドT0(メインスレッドのこと)で発生
・1バイトの書き込みをしようとした時にアドレス0x619000000580が違反した事を検知した
・test62.cpp の 11行目から呼び出された memset で発生(※コンパイラが自動的に memsetの代わりに __asan_memset を呼び出す処理に書き換えていた)
・アドレス 0x619000000580 は、0x619000000580 から始まる 1024バイトの領域の先頭である。
・test62.cppの8行目で スレッドT0によって解放済
・test62.cppの6行目で 以前はスレッドT0によって確保されていた。

【SUMMARY 以降】
・違反になったアドレスより前の領域は確保されていないヒープ領域(fa)
・違反になったアドレス以降は解放済みのヒープ領域(fd)

【ログから推測できる不具合の内容】

・free されたあとにアクセスしないようにシーケンスを制御し忘れている(アドレス変数をNULLに設定忘れとか。フラグ変更忘れとか。)

参考)上記のログを発生させたソースコード

#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
  // ヒープ確保
  char *ptr = new char[1024];
  // ヒープ解放
  delete [] ptr;

  // 解放したアドレスに対する操作
  memset(ptr, 0, 1);

  return 0;
}

参考)コンパイル・実行例

$ clang++ -g -O0 -o test62 -fsanitize=address test62.cpp
$ ./test62

「heap-use-after-free」への1件の返信

コメントを残す

メールアドレスが公開されることはありません。