2012-01-27 14 views
3

静的に定義された配列(つまり、malloc(1234)ではなくchar[1234])のバッファオーバーランを識別できるツールまたは方法はありますか?静的バッファオーバーランを識別/防止するためのツールと方法

私は最終的に以下の行によって引き起こされることが判明クラッシュと奇数行動追跡昨日の大半を費やし:

// ensure string is nul terminated due to stupid snprintf 
error_msg[error_msg_len] = '\0'; 

このインデックスは、明らかに、配列の境界を越えて書き込みを引き起こしたが。これにより、ポインタ変数が壊れてしまい、後でそのポインタで予期しない動作が発生します。

このような問題を軽減することができ頭に浮かぶ3つのものがある:

  1. コードレビュー

    これは実行されませんでしたが、私はそれに取り組んでいます。

  2. valgrind

    私は、多くの場合、メモリの問題を検出するために、開発中valgrindのを使用しますが、それは静的な配列を扱っていません。上記の例では、それは私には無効なfree()のclobberedポインタのような症状しか示されませんでした。過去には

  3. -fstack-protector-all

    私は、上記のようなそれは、このインスタンス内のフラグは何もしませんでしたいくつかの奇妙な理由でオーバーランを検出する-fstack-protector-allを使用しています。

どのように私がそのようなオーバーランを特定できるかについてのアイデアは誰でも提供できますか?上記のリストや全く新しいものを改善することによって。

EDIT:これまでの回答の中には、かなり高価な商品が挙げられています。この段階で私はそのようなツールを買う力を納得させることはできないと思うので、ツールを安く/無料に制限したいと思っています。はい、あなたはあなたが支払うものを手に入れますが、若干の改善は誰にも勝るものではありません。

+1

私はそれが質問された質問には関係ないと知っていますが、 'snprintf'はヌル終了します。 –

+0

私はこれらのエラーをキャッチするためにCoverityを使用しました。これは優れた静的解析ツールです。しかし、それは無料ではない(または安い) – TJD

+0

@スティーブ・ジェッソップ良い点。あなたが何らかの形で利用可能なバッファサイズ(それ自体の問題です)よりも多くを書いたならば、その種の保護が必要な 'sprintf'です。だから、その行にはバッファオーバーランがあっただけでなく、無意味でもあったことが判明しました。ブー。 –

答えて

2

スタティックアナライザツールは、の一部を検出することができます。バッファオーバーフロー。このコードの例

tst.c 9警告661:範囲外のポインタの可能性のあるアクセス(ここで

char bla[1024]; 
int i; 

for (i = 0; i <= 1024; i++) 
    bla[i] = 0; 

は何PC-Lintの/ flexelintレポートです1、データの終わりを超えて1)

+0

+1しかし、マニュアルの始めに 'lint with lint'の章を読んだり、メッセージがいっぱいになることを期待してください。 –

+0

@ShaneMacLaughlinはい、静的アナライザーの問題です。非常に冗長で、出力レポートを読むには時間がかかることがあります。 – ouah

+0

@ouah 'flexelint'は有料です。私は今、あなたがしようとしていることを推薦することができます他の静的なアナライザは何ですか? –

1

実験的なValgrindツール「SGCheck:実験的なスタックとグローバル配列を試したことがありますか?デフォルトの「memcheck」ツールとは対照的に、「オーバーラン検出器」ですか?

http://valgrind.org/docs/manual/sg-manual.html

私はそれを自分自身を試していないが、あなたが興味を持っているバグの種類の一部をカバーするように見えます。

明らかにValgrindは静的解析ではなく動的解析を行います。

0

私たちのCheckPointerツールは、場所に関係なく配列の範囲外エラーをキャッチする動的解析ツールです。

CheckPointerは、OPによって示された問題のように静的配列を含む、割り当てられた場所に関係なく、Valgrindは構造体フィールドまたは構造体フィールドの外にある参照を取得できません。 Valgrindは、このようなオーバーランを検出することはできません。これは、操作されているデータの実際の形状についての手がかりがないためです。これは、プログラミングランゲージの理解を必要とする。例えば、C.Valgrindは、割り当てられたメモリの外側の参照のみを検出することができる。 Checkpointerは、Cを親密に理解しているため、これを行うことができます。完全なコンパイラスタイルのCフロントエンドを使用して、タイプおよびクリティカルなサイズ情報を収集します。

現在、Cでは利用可能ですが、C++では利用できません。

関連する問題