1. ホーム
  2. c

[解決済み】スタックスマッシュを検出しました

2022-02-11 21:58:08

質問

a.outファイルを実行しているところです。実行後、プログラムがしばらく実行され、メッセージが表示され終了してしまいます。

**** stack smashing detected ***: ./a.out terminated*
*======= Backtrace: =========*
*/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted*

この場合、どのような原因が考えられるでしょうか。また、どのように修正したらよいでしょうか。

解決方法は?

スタックスマッシングは、バッファオーバーフローエラーを検出するためにgccが使用する保護メカニズムが原因で発生します。例えば、次のようなスニペットです。

#include <stdio.h>

void func()
{
    char array[10];
    gets(array);
}

int main(int argc, char **argv)
{
    func();
}

コンパイラ(この場合gcc)は、既知の値を持つ保護変数(カナリアと呼ばれる)を追加します。10を超える文字列を入力すると、この変数が破壊され、SIGABRTが発生してプログラムが終了します。

gccのこの保護機能を無効にするには、オプションの -fno-stack-protector をコンパイルしてください。この場合、別のエラーが表示されます。おそらく、不正なメモリ位置にアクセスしようとしているため、セグメンテーション・フォールトが発生するのでしょう。 なお -fstack-protector セキュリティのため、リリースビルドでは常にオンにしておく必要があります。

デバッガでプログラムを実行することで、オーバーフローのポイントについてある程度の情報を得ることができます。Valgrind はスタック関連のエラーではうまく機能しませんが、デバッガのように、クラッシュの場所と理由をピンポイントで特定するのに役立つかもしれません。