質問: 7483294672645692748739827964726579478927927424252526; ← 算術オーバーフローですよね?? int i と int ff の値は書き換わらないのですが・・・・・・・・ どういうことでしょうか?
回答: -fstack-protectorの効果はこのページに書かれています。 つまり、「スタックを破壊したことで関数の戻り値アドレスが書き換わってしまったことを検出して、不当なアドレスへリターンせずにプログラムを異常終了させる」のが目的です。なおスタックを破壊することと「スタックオーバーフロー」は別の話です。スタックオーバーフローとは「関数の呼び出しの入れ子が深くなりすぎて実行スタックが足りなくなる」ことです。 このオプションを有効にした際にうれしいのは次のようなプログラムコードを実行した場合です。 ``` int f() { int x[4]; int index = 0; for (int i = 0; i < 10; i++) { x[index++] = 0; } return 0; } int main(int argc, char* argv[]){ f(); } ``` 上記をgcc -fstack-protector-allでコンパイルして実行すると、f()からリターンする際にエラーが検出され以下のようなメッセージとともにプログラムが異常終了してくれます。 `*** stack smashing detected ***: ./a.out terminated` 最初に挙げたページに書かれているように、この動作はスタックフレーム上の関数のリターンアドレス付近に「値が破壊されていることを検出するためのカナリア」と呼ばれるデータを配置し、リターン時にこのカナリアが破壊されていないことをチェックして破壊されていたら異常終了するという手法で実現されているようです。 つまりこのオプションは「**スタックを破壊されること自体を防ぐものではなく**」「破壊されている状態で不当アドレスへ分岐することだけを防ぐ」ものです。それをもって「バッファーオーバーランを利用して不当なコードを実行する」ようなセキュリティー上の脅威に対抗するものといえるのでしょう。 `-fno-stack-protector` を指定すると、上記のカナリア破壊検出が生成されなくなるだけです。 > > 他になんのセキュリティ機能で保護されているのでしょうか?? > > > そもそもC言語で普通にコンパイルしても特にセキュリティー機能はないと考えてもよいと思いますよ。プログラマーがそうしようと意図すればメモリーは破壊し放題です。どこがどう破壊されるかによってプログラムは異常終了することもあればデータが不正のまま何食わぬ顔をして正常終了することもあります。 何かを意図的に起こしたいなら「スタック上のローカル変数がどう割り当てられて自分のコードが正確にどこをどういう値に書き換えるのか」を把握してください。ご質問に書かれているようなざっくりした情報ではそれを確認したとはいえないと思います。スタックフレーム上にローカル変数や関数の引数、関数の戻り値などがどう配置されているかまでを厳密に調べると、どう動くかが予測できます。