質問: バッファオーバーフローを出そうと思って、以下のコードを実行したところ「a」を13文字入力するとプログラムが停止します。 12文字入力すると入力した文字がそのまま出力されますが、何故13文字入力するとプログラムが停止するのでしょうか? ``` #include int main(void) { char str[1]; scanf("%s", str); printf("%s", str); return 0; } ```
回答: C言語でバッファオーバーフローが発生した場合の動作は**未定義**です。未定義な動作とは、どのような動作が起きるかはわからないことを意味します。OS、コンパイラ、コンパイル時のオプション、実行時の環境、OSを含む各種設定、等々によって、そのまま正常に動いたり、動作自体が無視されり、エラーになったり、任意のコマンドが実行できたり、等の予測不可能な現象が発生します。12文字では正常っぽい動作で、13文字でエラーになったのは、**ただの偶然です**。あなたの環境はたまたまそのような動作をするようにコンパイルされていて実行されたに過ぎません。OSを変えたり、コンパイラを変えたり、コンパイル時のオプションを変えたり、実行するタイミングを変えたりしたら、5文字でエラーになるとか、逆に100文字でも出力できるとか、いろいろと変わる可能性があります。「バッファオーバーフローは何文字まで大丈夫か?」という問いには、C言語の規格としては「0文字までは大丈夫だけど、1文字でも溢れたら、何が起きるかは予測は不可能」と答えるしかありません。 それでも、なぜ12文字と13文字で変わるのかを知りたいのであれば、どのような環境でどのようにコンパイルされてどのように動作するのかを細かく分析しないとわかりません。OS(細かいバージョンまでです。Windows 10ではなくWindows 10 Pro, バージョン: 1703, OSビルド: 15063.483と言ったところまで知る必要があります)、コンパイラ(単にVC++とかではなく、こちらもバージョンやアップデートも含めてです)、コンパイル時のオプション(コンパイルそのものへの設定があれば、それも含めて)、実行環境(データ実行防止(DEP)の有無、ウィルススキャンソフトの有無、その他のセキュリティ関係のポリシー)を知る必要があります。コンパイルされたバイナリを逆アセンブラで解析し、スタックへの書き込みをエミュレートしながら、バッファオーバーフロー時にどのようにメモリが変更され、問題があるかないかを見る必要があります。かなり高度な知識が要求されますが、よくあるバッファオーバーフローをついて任意コマンド実行を行う方法(いわゆるバッファオーバーフローに起因する脆弱性というものです)を調べる場合は必須の技術ですので、セキュリティー分野に進みたいのであれば身につけておいて損はありません。