スタック保護
ソフトウェアでは、スタックバッファのオーバーフローは、プログラムが通常固定長バッファである意図したデータ構造外のプログラムのコールスタック上のメモリアドレスに書き込むときに発生します。その結果、ほとんどの場合、近くのデータが破損し、どの関数を返すかまで変更します。それが意図的であれば、それはスタックスマッシングと呼ばれます。 スタックバッファオーバーフローから保護する1つの方法は、スタックカナリーと呼ばれ、炭鉱にカナリヤを使用することに由来しています。
IAR C/C++コンパイラのスタック保護
IAR C/C++コンパイラfor Armは、スタック保護をサポートします。
危険
スタック保護を必要な関数で有効にするには、コンパイラオプション‑‑stack_protectionを使用します。詳細については、‑‑stack_protectionを参照してください。
スタック保護のIARの実装に、ヒューリスティックを使用して関数にスタック保護が必要かどうかを決定します。定義したローカル変数に配列型、または配列型として含まれる構造体型がある場合、関数にはスタック保護が必要です。さらに、ローカル変数のアドレスが関数外に伝播される場合、そのような関数もスタック保護が必要です。
関数にスタック保護が必要な場合、ローカル変数は、関数スタックブロックの一番高いところに配置するために、配列型の変数でソートされます。これらの変数の後、カナリー要素が配置されます。カナリーは関数の入口で初期化されます。初期値はグローバル変数__stack_chk_guardから取得されます。関数の終了で、コードはカナリー要素がまだ最初の値を含むかどうかを検証します。含まれない場合は、関数__stack_chk_failが呼び出されます。
アプリケーションにスタック保護を使用
スタック保護を使用するには、お使いのアプリケーションでこれらのオプションを定義する必要があります。
extern uint32_t __stack_chk_guard初めて使用する前に、グローバル変数
__stack_chk_guardを初期化しなければなりません。初期値はランダムにすると、より安全です。__interwork __nounwind __noreturn void __stack_chk_fail(void)関数
__stack_chk_failの目的は、問題を通知しアプリケーションを終了することです。注: この関数が返すアドレスは、失敗した関数を示すためのものです。
arm\src\lib\\runtimeディレクトリのstack_protection.cファイルは、__stack_chk_guardおよび__stack_chk_failの両方のテンプレートとして使用できます。