2009-11-15 26 views
7

だから私は、簡単なバッファオーバーフローを示すコードのこのシンプルな作品があります。Cでバッファオーバーフローを検出するツールはありますか?

#include <stdio.h> 

int main(void) 
{ 
    char c[4] = { 'A', 'B', 'C', 'D' }; 
    char d[4] = { 'W', 'X', 'Y', 'Z' }; 

    printf("c[0] is '%c'\n", c[0]); 

    d[4] = 'Z'; /* Overflow that overwrites c[0] */ 

    printf("c[0] is '%c'\n", c[0]); 

    return 0; 
} 

出力:

$ ./a.out 
c[0] is 'A' 
c[0] is 'Z' 

を、私は、次のgccのオプションで、このコードをコンパイルしようとしていると、それは飛行を持つ合格色:

gcc -Wall -Wextra -Wformat=2 -Wswitch-default -Wcast-align -Wpointer-arith \ 
    -Wbad-function-cast -Wstrict-prototypes -Winline -Wundef -Wnested-externs \ 
    -Wcast-qual -Wshadow -Wwrite-strings -Wconversion -Wunreachable-code \ 
    -Wstrict-aliasing=2 -ffloat-store -fno-common -fstrict-aliasing \ 
    -Wstack-protector -fstack-protector-all -std=c99 -pedantic -O0 -ggdb3 

私もlibefenceとvalgrindのを試してみました。ヒープ上の読み書きをキャッチするように作られて以来、私は寛容が通過することを期待していましたが、バンググラインドが合格したことに驚いていました。

このコードは、c [4]とd [0]が重複しているため、Segfaultを生成しません。

だから、何がありますかCANこれをキャッチしますか? Linux上で動作するものは何か自由であるだろう。

+0

最新バージョンを試すことができます。 –

+0

あなたは正しいですが、それは残念ですが、「cppcheck」はそうです! – SiegeX

+0

gccはこれをキャッチしませんが、しばらく前に逆参照されていなかった配列の最後のポインタについて偽の警告を出していたコンパイラのバグを回避する必要があったことを考えてください。 http://stackoverflow.com/questions/1168525/c-gcc4-4-warning-array-subscript-is-above-array-boundsを参照してください。私はgcc *がこれを診断しようとしていると思います。あなたのオプションがそれを無効にするか、反対のコンパイラのバグを見つけました。 –

答えて

5

お試しcppcheckそれは私のために働いた。

+0

「cppcheck」の呼び出しが良いです。前にこのソースアナライザーについて聞いたことはありませんでしたが、*エラーが見つかりました! – SiegeX

+1

新しいURLは次のとおりです。http://cppcheck.sourceforge.net/ –

+0

@AndrewSchoolsありがとうございます。 URLが更新されました。 – Teddy

0

もし私がLinux上にあるのであれば、まずvalgrindを試してみてください。私はそれを扱うと思います。

編集: SiegeX私は(それは、それが唯一のプロセスの実行時に関与しているとして、スタック上の警備員を挿入する方法がありませんので、理にかなっている)Valgrindのはないと思うと言うようにそれがある場合。とにかくあなたのツールボックスに入れておく価値があるのは良いツールですので、私は投稿を保管します。

+3

Valgrind *質問に明記されているようにこれをキャッチしません。 。投票を中止してください。編集後の – SiegeX

+0

-1は本当に公正ではなかった。 – Fredrik

+0

@SiegeX:「Valgrindもパスしています」というのは、それをキャッチしているように見えます。ヒープ割り当てされたメモリをキャッチするように設計されているので、私はそれに対処することを期待していなかったので、私は少し驚いたと言わなければならない。 – Vatine

-1

リテラル文字列を参照しているので、この場合は暗黙のヌル文字があると思います。したがって、d [4]はまだ境界内にあります(const char *として想像してください)....私は間違っているかもしれません。

+1

私はそれをc [5] = "ABCD"と宣言していました。コンパイラは最後にNULバイトをスローします。しかし、4文字しかないNULバイトの余地がないので、それは破棄されます。しかし、混乱を減らすために、初期化にcharを明示的に使用するようにコードを変更しました。 – SiegeX

2

valgrindはバイナリで動作するため、このコードでは何も問題はありませんでした。これらの(http://www.thefreecountry.com/programming/debuggers.shtml)スタティックソースコードアナライザーを確認してください。それらがうまくいかない場合は、PC-lint(http://www.gimpel.com/html/pcl.htm)がこれを処理します....

+0

+1静的なソースアナライザを推薦するための+1 ...バングラディンのようなものがなければ、おそらくそれを捕まえる可能性が高いです(そしてそれについて考えると、バングラディンはそれを見つけられないと思います – Fredrik

+0

あなたの 'debuggers.shtml'リンクは 'cppcheck'(受け入れられた答え)については言及していませんが、そうでない場合は非常に良いリンクです。ありがとう – SiegeX

+0

私は前にcppcheckについて聞いたことがありません。 2007年の最古のリリースは比較的新しいものです。特に、PC-Lintと比較すると... – Malkocoglu

1

Rational Purifyは、バッファオーバーフロー、メモリリーク、破損などを検出するのに非常にうまく機能します。

memパッケージは、in this SO answerと記載されています。

1

Coverity(静的解析ツール)がこれをキャッチします。

0

バッファオーバーフローは実行時まで発生しないため、Cでのキャッチがかなり困難です。それを引き起こす可能性を最小限に抑えるには、いくつかの境界チェックを行うやや安全な標準ライブラリ関数を使用する必要があります。 gets()の代わりにfgets()を使用します。

多くの配列を手動で操作する場合は、おそらくアルゴリズムのエッジケースをチェックするための単体テストを書くべきです。 Cmockeryは、Cの単体テストフレームワークの一例です。

+0

この特定のバッファオーバーランは、コードが(静的に)*(c + 4)にアクセスし、c + 3が最後の有効なアドレスである割当でキャッチ可能なコンパイル時間になります。 – Vatine

0

Valgrindは自動ストレージと静的ストレージでオーバーフローを検出しません。少なくともデフォルトではありません。 IIRCを動作させるには、デフォルトの "memcheck"ではなく、いくつかのオプションをオンにするか、それに付属の "開発中"ツールを実行する必要があります。

+0

私は最新のvalgrind 3.5.0にアップグレードし、--tool = exp-ptrcheckを使用しましたが、これは警告とエラーがゼロになっています。 – SiegeX

0

ビジュアルスタジオ(-Ziと思うが間違っている可能性がある)は、ランタイムスタックチェッカーでこの種の割り当てをキャッチします。あなたが好む無料のLinuxソリューションではありませんが、うまく動作します。

2

Bugfighter C/C++で試してください。

私は毎日それを使用し、array[5][5][5]のような多次元配列であってもうまく動作します。

BugfighterのWebページはwww.bugfighter-soft.comです。

2

valgrindののmemcheckは、スタックのヒープメモリ

について検出され、あなたは、残念ながら、これをキャッチしていないスプリントのvalgrindののSGCheck

関連する問題