通常のコードがオーバーフローする可能性があることはわかっています。
文字列[9];
scanf("%s", 文字列)。
しかし、scanf("%8s", string) をオーバーフローさせることは可能ですか? 8はほんの一例です。
「%8s」が区切りのように機能することは知っていますが、8 文字を超える文字列を入力すると、次の理由でプログラムが終了することにも気付きました。
* スタック破壊が検出されました * : ./a.out が終了しました
======= バックトレース: =========
...
明らかに、GCC によってデフォルトでオンになっているスタック破壊を検出するフラグがあります。これはスタック破壊であるため、オーバーフローして任意のコードを実行する可能性はまだあると思います。
scanf("%s") の呼び出し元を台無しにする通常のオーバーフローとは対照的に、scanf("%8s") がオーバーフローする可能性がある場合は、scanf 関数内でオーバーフローするため、scanf が戻ろうとすると制御が取得されます。
しかし、scanf はモード切り替え (ユーザー モードからカーネル モードへの切り替え) を必要とする syscall であり、内部的には標準入力への読み取りなどを呼び出します。そのため、カーネル モードなどでオーバーフローする可能性があるかどうかはわかりません。
コメント大歓迎です!!
更新 >>
上記の例では、char string[9] が想定されています。次の実際のコードの char string[8]。
問題は、スタック破壊による安全な scanf("%8s") と GCC の中止の間の矛盾するように見える話についてです。
簡略化されたコード:
void foo(pass some pointer) {
char input[8];
int input_number = 0;
while (1) { // looping console
printf some info;
scanf("%8s", input);
input_number = atoi(input);
if ((strlen(input) == 1) && (strncmp(input, "q", 1) == 0)) {
input_number = -1;
}
switch (input_number) {
case -1: to quit the console if input = 'q';
default: to print info that pointer refers to;
...
}
}
}
ノート:
- foo は他の誰かによって呼び出されます。
- string は実際のコードでは "%8s" で 8 バイトですが、これがスマッシングにつながることはないと思います。