前回の記事の続き。
CppCheckでC言語/C++のメモリリーク(解放漏れ)を静的解析で検出する
Cppcheckを利用して、バッファオーバーランを検出したい。
バッファオーバーランとは、バッファオーバーフロー、メモリ破壊、メモリ不正番地アクセスとも言われていて、組込みエンジニアを一瞬のうちに恐怖に戦かせる魔法のぽぽぽぽーんだ。
いろんなパターンのメモリ破壊をCppCheckで検出できるか、遊んでみた。
メモリ解放したあとにアクセスしてしまうパターン
void buffer\_over\_run(void)
{
char *p;
p = (char *)malloc(1);
free(p);
*p = 3;
}
$ cppcheck -enable=all memory_leak.c
Checking memory_leak.c
[memory_leak.c:21]: (error) Dereferencing 'p' after it is deallocated / released
[memory_leak.c:21]: (error) Uninitialized variable: p
Checking usage of global functions..
関係ないメモリ領域に勝手にデータを書き込んでしまう領域破壊パターン
void buffer\_over\_run(void)
{
char *p;
p = (char *)malloc(1);
memset(p,"c",2);
free(p);
}
$ cppcheck -enable=all memory_leak.c
Checking memory_leak.c
[memory_leak.c:11]: (error) Buffer is accessed out of bounds.
Checking usage of global functions..
配列で宣言した領域をオーバーするパターン
void buffer\_over\_run(void)
{
char c[5];
c[5] = 3;
}
$ cppcheck -enable=all memory_leak.c
Checking memory_leak.c
[memory_leak.c:8]: (style) Variable 'c' is assigned a value that is never used
[memory_leak.c:21]: (error) Array 'c[5]' accessed at index 5, which is out of bounds.
Checking usage of global functions..
インクリメントすることで、知らないうちに不正番地アクセス
void buffer\_over\_run(void)
{
char *p;
p = (char *)malloc(1);
p++;
*p = 1;
printf(“%x”,p);
free(p);
}
$ cppcheck -enable=all memory_leak.c
Checking memory_leak.c
Checking usage of global functions..
あれ、検出してくれない・・・・そして
$ ./a.exe *p = 800482a8 Aborted (コアダンプ)
ちょ・・・・なんとかしてよ。
おまけ
ネットを徘徊していたら、メモリ破壊についての面白い詩をみつけた。
直接引用はチョッと気が引けるので、参考リンクとしてリンク貼っておく。