具体例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