8.158 --protect_stack、--no_protect_stack

脆弱な各関数のスタックフレームにガード変数を挿入します。

保護変数は、バッファとリターンアドレスエントリの間に挿入されます。
関数は、脆弱な配列を含んでいる場合に、脆弱であると見なされます。脆弱な配列とは、次のような配列です。
  • 自動保存期間。
  • 文字型(char または wchar_t)。
ガード変数とチェックを挿入するほかに、コンパイラは脆弱な配列をスタックの一番上の、ガード変数の直前に移動します。コンパイラによってガード変数の値のコピーが別の場所に保存され、防御が上書き(バッファオーバーフローを示す)されていないことを確認するために使用されます。

使用法

--protect_stack を使用して、スタック保護機能を有効にします。代わりに --no_protect_stack を使用して、この機能を明示的に無効にします。両方のオプションが指定されている場合は、最後に指定されているオプションが有効になります。
--protect_stack_all オプションは、脆弱性にかかわりなく、この保護をすべての関数に追加します。
スタック保護を使用すると、脆弱な関数が呼び出された場合、そのガード変数の初期値はグローバル変数から取り出されます。
void *__stack_chk_guard;
この変数にはランダム値などの適切な値を指定する必要があります。値はプログラムのライフサイクル中に変更できます。たとえば、別のスレッドが継続的に値を変更するのが適切な実装となる場合があります。さらに、次の関数を実装する必要があります。
void __stack_chk_fail(void);
この関数は、防御の失敗が検出されるとチェックコードによって呼び出されます。通常、このような関数は、エラーが報告された後に終了します。
GNU ツールとの整合性を図るために、オプション -fstack-protector --protect-stack と同じように取り扱われます。同様に、-fstack-protector-all オプションは --protect_stack_all と同様に取り扱われます。

デフォルト

デフォルトは --no_protect_stack です。

次の関数では、配列 buf は脆弱です。--protect_stack を使用してコンパイルした場合、関数は保護されます。
void copy(const char *p)
{
    char buf[4];
    strcpy(buf, p);
}
非機密扱いPDF file icon PDF 版ARM DUI0472LJ
Copyright © 2010-2015 ARM.All rights reserved.