GCCのスタック保護機能を使用するタイミングと方法は?
-
06-07-2019 - |
質問
作業中のプロジェクトのコンパイル時に -Wstack-protector
警告を有効にしました(GCC 4.2を搭載したMac OS X 10.6でコンパイルする商用マルチプラットフォームC ++ゲームエンジン)。
このフラグは、 -fstack-protector
が有効になっていてもスタックの破壊から保護されない関数について警告します。
GCCは、プロジェクトをビルドするときに警告を発します。
機能を保護しない:少なくとも8バイト長のバッファーなし
ローカル変数を保護しない:可変長バッファー
最初の警告では、関数で使用するときにバッファーが持つ必要がある最小サイズを調整できることがわかりました。この関数はスタックスマッシングから保護されます。-param ssp-buffer-size = X
を使用できます。Xはデフォルトで8で、1に設定できます。
2番目の警告については、 -Wstack-protector
の使用を停止しない限り、その発生を抑制できません。
-
-fstack-protector
はいつ使用する必要がありますか? (たとえば、開発中に常に、またはバグを追跡するときなど) -
-fstack-protector-all
はいつ使用する必要がありますか? -
-Wstack-protector
から何がわかりますか?バッファーの最小サイズを減らすことを示唆していますか? - その場合、サイズを1に設定することには欠点がありますか?
- 警告のないビルドが必要な場合、
-Wstack-protector
は常に有効にしたい種類のフラグではないようです。これは正しいですか?
解決
スタック保護は強化戦略であり、デバッグ戦略ではありません。ゲームがネットワーク対応であるか、制御されていないソースからのデータがある場合は、オンにします。管理されていない場所からのデータがない場合は、有効にしないでください。
次のようになります:バグがあり、攻撃者が制御できるものに基づいてバッファを変更した場合、攻撃者は戻りアドレスまたはスタックの同様の部分を上書きして、あなたの代わりにコードを実行させることができますコード。スタック保護は、これを検出するとプログラムを中止します。ユーザーは満足しませんが、ハッキングされることもありません。これはゲーム内での不正行為に関するハッキングではなく、コードの脆弱性を利用してユーザーに感染する可能性のあるエクスプロイトを作成するハッキングのようなものです。
デバッグ指向のソリューションについては、mudflapなどをご覧ください。
特定の質問について:
- 制御されていないソースからデータを取得する場合は、スタックプロテクターを使用します。これに対する答えはおそらくイエスです。それを使用します。制御されていないソースからのデータを持っていなくても、おそらく最終的にはすでに、あるいはすでに気づいていないでしょう。
-
パフォーマンスの低下と引き換えに追加の保護が必要な場合は、すべてのバッファーのスタック保護を使用できます。 gcc4.4.2マニュアルから:
-fstack-protector
スタックスマッシング攻撃などのバッファオーバーフローをチェックするための追加コードを発行します。これは、脆弱なオブジェクトを持つ関数にガード変数を追加することにより行われます。これには、allocaを呼び出す関数、および8バイトを超えるバッファーを持つ関数が含まれます。ガードは、関数に入るときに初期化され、関数が終了するときにチェックされます。ガードチェックが失敗すると、エラーメッセージが出力され、プログラムが終了します。
-fstack-protector-all
すべての機能が保護されていることを除いて、-fstack-protectorと同様です。
-
警告は、スタック保護で保護できないバッファを示します。
- 必ずしも最小バッファサイズを小さくすることを推奨しているわけではなく、0/1のサイズでは、stack-protector-allと同じです。バッファが保護されるようにコードを再設計することを決定した場合に、できるように、それはあなたにそれを指摘しているだけです。
- いいえ、これらの警告は問題を表すものではなく、単に情報を示しているだけです。定期的に使用しないでください。
他のヒント
実際には、通常のビルドの警告を気にする必要はありません。それは本当に情報メッセージです。スタック上の可変サイズのバッファに固有のセキュリティ上の懸念があることは明らかであることを願っています。サイズの計算が間違っていて、大きな穴が開いている。