• このエントリーをはてなブックマークに追加

前回の記事の続き。

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 (コアダンプ)

ちょ・・・・なんとかしてよ。

おまけ

ネットを徘徊していたら、メモリ破壊についての面白い詩をみつけた。
直接引用はチョッと気が引けるので、参考リンクとしてリンク貼っておく。

諸君、私はC言語が好きだ