エラー: dynamic-stack-buffer-overflow
Address Sanitizer エラー: dynamic-stack-buffer-overflow
この例は、スタック割り当てオブジェクトの境界外のバッファー アクセスに関するエラーを示しています。
例 - alloca
オーバーフロー (右)
// example1.cpp
// dynamic-stack-buffer-overflow error
#include <malloc.h>
__declspec(noinline)
void foo(int index, int len) {
volatile char *str = (volatile char *)_alloca(len);
// reinterpret_cast<long>(str) & 31L;
str[index] = '1'; // Boom !
}
int main(int argc, char **argv) {
foo(33, 10);
return 0;
}
この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。
cl example1.cpp /fsanitize=address /Zi
devenv /debugexe example1.exe
結果のエラー
例 - alloca
オーバーフロー (左)
// example2.cpp
// dynamic-stack-buffer-overflow error
#include <malloc.h>
__declspec(noinline)
void foo(int index, int len) {
volatile char *str = (volatile char *)_alloca(len);
str[index] = '1'; // Boom!
}
int main(int argc, char **argv) {
foo(-1, 10);
return 0;
}
この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。
cl example2.cpp /fsanitize=address /Zi
devenv /debugexe example2.exe
結果のエラー - alloca
オーバーフロー (左)
例 - alloca
へのいくつかの呼び出し
// example3.cpp
// dynamic-stack-buffer-overflow error
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define SIZE 7
extern void nothing();
int x=13,*aa,*bb,y=0;
int fail = 0;
int tmp;
int main()
{
int* cc;
int i;
int k = 17;
__try {
tmp = k;
aa = (int*)_alloca(SIZE * sizeof(int));
if (((int)aa) & 0x3)
fail = 1;
for (i = 0; i < SIZE; i++) {
aa[i] = x + 1 + i;
}
bb = (int*)_alloca(x * sizeof(int));
if (((int)bb) & 0x3)
fail = 1;
for (i = 0; i < x; i++) {
bb[i] = 7;
bb[i] = bb[i] + i;
}
{
int s = 112728283;
int ar[8];
for (i = 0; i < 8; i++)
ar[i] = s * 17 * i;
}
cc = (int*)_alloca(x);
if (((int)cc) & 0x3)
fail = 1;
cc[0] = 0;
cc[1] = 1;
cc[2] = 2;
cc[3] = 3; // <--- Boom!
for (i = 0; i < x; i++)
if (bb[i] != (7 + i))
fail = 1;
if (tmp != k)
fail = 1;
if (fail) {
printf("fail\n");
exit(7);
}
printf("%d\n", (*cc) / y);
printf("fail\n");
exit(7);
}
__except (1)
{
for (i = 0; i < SIZE; i++)
if (aa[i] != (x + i + 1))
fail = 1;
if (fail) {
printf("fail\n");
exit(7);
}
printf("pass\n");
exit(0);
}
}
この例をビルドしてテストするには、Visual Studio 2019 バージョン 16.9 以降の開発者コマンド プロンプトで次のコマンドを実行します。
cl example3.cpp /fsanitize=address /Zi
devenv /debugexe example3.exe
結果のエラー - alloca に対する複数の呼び出し
関連項目
AddressSanitizer の概要
AddressSanitizer の既知の問題
AddressSanitizer のビルドと言語リファレンス
AddressSanitizer ランタイム リファレンス
AddressSanitizer シャドウ バイト
AddressSanitizer クラウドまたは分散テスト
AddressSanitizer デバッガーの統合
AddressSanitizer エラーの例