web-dev-qa-db-ja.com

「スタックスマッシング検出」をデバッグするにはどうすればよいですか?

複雑なc ++コードがあります。

http://althenia.net/fcgicc を使用するFastCGIプログラムです。

Looooong urlを要求すると、

*** stack smashing detected ***: ./tileserve terminated
Erreur de segmentation

実際には、私はそれほど長いURLを使用したことがないので問題ではありませんが、誰でも私のサーバーを終了できる可能性があることを意味します。

問題が発生する場所を見つけるためのツール(およびその使用方法)はありますか?

編集:解決

解決しました。

やっていた

int len;
char uri[200];

len = strlen(request.params[std::string("REQUEST_URI")].c_str());
printf("%d\n", len);

if (len > 200) return 1;

strcpy(uri, request.params[std::string("REQUEST_URI")].c_str());

200はlenテストには高すぎたようです。実際には194で失敗します。

だから私はしました:

if (len > 190) return 1;

今、大丈夫です。

19
user1219721

Webサイトを読むと、これがCライブラリの単純なC++ラッパーであることがわかります。

Cライブラリの一般的な問題は、バッファオーバーランです。

#include <cstring>
#include <cstdio>

int main(int argc, char* argv[]) {
  char buffer[16]; // ought to be sufficient

  strcpy(buffer, argv[1]);
  printf("%s", buffer);
}

このプログラムを試してください:

> ./test "a"
a
> ./test "abcdefghijklmnoprqstuvwxyz"
???

バッファには16文字しか含めることができないため、残りの文字は最後を超えて書き込まれます。これはstack smashing、およびndefined behaviorです。

ランタイムライブラリまたはOSの実装の多くは、状況によってはこの状況を検出してプログラムを終了する場合があります。

あなたが何か間違っているか、またはライブラリが間違っています。

問題を特定するには、Valgrindを使用するか、デバッガーでプログラムを実行します。または、システムで許可されている場合は、プログラムが強制終了されたときにメモリダンプが発生する可能性があります。このメモリダンプをデバッガで表示することもできます。

17
Matthieu M.

Valgrindなどを使用するか、コンパイラーが静的分析を行って、バッファーをオーバーランしている可能性のある場所を見つけることができます。

また、strcpyなどのエラーが発生しやすい関数の使用についてコードを監査し、それらをstrncpyなどの安全な関数に置き換えることもできますが、std :: stringなどの独自のメモリを管理するオブジェクトを使用することもできます。

1
bames53