heap-buffer-overflow

具体例1: mallocで確保した領域周辺でのmemset(ランタイムライブラリ)でのエラー

レポート結果

ログからわかること

・対象のプロセスIDは 24797
・アドレス 0x619000000980 において、heap-buffer-overflow を検出した
・PCレジスタが 0x000104fd7aa8, BPレジスタが 0x7ffeeac7fa00, SPレジスタが 0x7ffeeac7f1b0 の状態だった

・スレッドT0(メインスレッドのこと)で発生
・1025バイトの書き込みをしようとした時にアドレス0x619000000980が違反した事を検知した
(※0x619000000980からの1025バイトの書き込みという意味ではない)
・test11.cpp の 9行目から呼び出された memset で発生(※コンパイラが自動的に memsetの代わりに __asan_memset を呼び出す処理に書き換えていた)
・アドレス 0x619000000980 は、1024バイト分確保された 0x619000000580(以降) 〜 0x619000000980(未満) の範囲外
・1024バイトのバッファはtest11.cppの6行目にあるmallocでスレッドT0によって確保された(※コンパイラが自動的に malloc の代わりに wrap_malloc を呼び出す処理に書き換えていた)

SUMMARY 以降】
・違反になったアドレスより前の領域は普通にアクセスできる(00)
・違反になったアドレス以降は確保されていないヒープ領域(fa)

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

・確保すべきバッファのサイズが小さい(確保サイズを間違えている)
・格納する内容が大きい(格納サイズを間違えている)
・先頭アドレスの計算を間違えている(オフセット計算)

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

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

int main(int argc, char *argv[]) {
  // 1024バイト分のヒープ領域を確保
  char* buffer = (char*) malloc(1024);

  // 確保した領域(1024) よりも 1 バイト多く書き込む
  memset(buffer, 0, 1024 + 1);

  return 0;
}

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

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

具体例2: mallocで確保した領域周辺以外でのmemset(ランタイムライブラリ)でのエラー

レポート結果

ログからわかること

・対象のプロセスIDは 24990
・アドレス 0x619000000d80 において、heap-buffer-overflow を検出した
・PCレジスタが 0x000100953aa8, BPレジスタが 0x7ffeef301a00, SPレジスタが 0x7ffeef3011b0 の状態だった

・スレッドT0(メインスレッドのこと)で発生
・1バイトの書き込みをしようとした時にアドレス0x619000000d80が違反した事を検知している

・test12.cpp の 9行目から呼び出された処理で発生(※コンパイラが自動的に memsetの代わりに __asan_memset を呼び出す処理に書き換えていた)
・アドレス 0x619000000d80 は wild pointer である(≒不正なアドレス)

SUMMARY 以降】
・違反になったアドレスの前も後も確保されていないヒープ領域(fa)

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

・先頭アドレスの計算を間違えている(オフセット計算)

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

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

int main(int argc, char *argv[]) {
  // 1024バイト分のヒープ領域を確保
  char* buffer = (char*) malloc(1024);

  // 確保した領域外(確保した領域よりも 2048 バイト後ろ)に対して 1 バイト書き込む
  memset(buffer + 2048, 0, 1);

  return 0;
}

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

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

具体例3: newで確保した領域周辺でのエラー

レポート結果

ログからわかること

・対象のプロセスIDは 25237
・アドレス 0x619000000980 において、heap-buffer-overflow を検出した
・PCレジスタが 0x00010a46cf07, BPレジスタが 0x7ffee57939f0, SPレジスタが 0x7ffee57939e8 の状態だった

・スレッドT0(メインスレッドのこと)で発生
・1バイトの書き込みをしようとした時にアドレス0x619000000980が違反した事を検知している

・test13.cpp の 8行目から呼び出された処理で発生
・アドレス 0x619000000980 は、1024バイト分確保された 0x619000000580(以降) 〜 0x619000000980(未満) の範囲外
・1024バイトのバッファはtest13.cppの5行目にあるnewでスレッドT0によって確保された(※コンパイラが自動的に new の代わりに wrap__Znam を呼び出す処理に書き換えていた)

SUMMARY 以降】
・違反になったアドレスより前の領域は普通にアクセスできる(00)
・違反になったアドレス以降は確保されていないヒープ領域(fa)

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

・確保すべきバッファのサイズが小さい(確保サイズを間違えている)
・格納する内容が大きい(格納サイズを間違えている)
・先頭アドレスの計算を間違えている(オフセット計算)

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

#include <stdlib.h>

int main(int argc, char *argv[]) {
  // 1024バイト分のヒープ領域を確保
  char* buffer = new char[1024];

  // 確保した領域の有効なインデックス(0以上〜1024未満)を超えて、1 バイト書き込む
  buffer[1024] = '\0';

  return 0;
}

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

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

コメントを残す

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