誰かがgcc -D_FORTIFY_SOURCE=1
と-D_FORTIFY_SOURCE=2
の違いを指摘できますか? =2
の方が安全だと思いますか?ポイントごとに違いをリストしたリストを見つけることができませんでした。
また、-D_FORTIFY_SOURCE=2
を-O2
とともに使用する必要があることも読んでいます。そうしないと、すべての機能が使用可能になりません。また、ここで私は詳細に回帰を指定するリストを見つけていません。ターゲットはフラッシュメモリがそれほど多くないデバイスなので、-Os
でコンパイルすることに特に興味があります。
これが文書化されている場所に関するヒントは歓迎します!
機能テストマクロのマニュアルページから( man 7 feature_test_macros
)
_FORTIFY_SOURCE
(glibc 2.3.4以降)このマクロを定義すると、さまざまな文字列およびメモリ操作関数(たとえば、
memcpy
、memset
、stpcpy
、strcpy
、strncpy
、strcat
、strncat
、sprintf
、snprintf
、vsprintf
、vsnprintf
、gets
、およびそれらのワイド文字バリアント)。一部の関数では、引数の一貫性がチェックされます。たとえば、指定されたフラグにO_CREAT
が含まれる場合、open
にmode引数が指定されているかどうかのチェックが行われます。すべての問題が検出されるわけではなく、いくつかの一般的なケースが検出されます。
_FORTIFY_SOURCE
が1に設定され、コンパイラー最適化レベル1(gcc -O1
)以上の場合、適合プログラムの動作を変更してはならないチェックが実行されます。
_FORTIFY_SOURCE
を2に設定すると、さらにいくつかのチェックが追加されますが、一部の適合プログラムは失敗する可能性があります。一部のチェックは、コンパイル時に(ヘッダーファイルに実装されたマクロロジックを介して)実行でき、コンパイラ警告が発生します。他のチェックは実行時に行われ、チェックが失敗すると実行時エラーが発生します。
このマクロを使用するには、バージョン4.0以降の
gcc
で利用可能なコンパイラサポートが必要です。
さらに、記事 FORTIFY_SOURCEでアプリケーションのセキュリティを強化する (2014年3月)は次のように述べています。
gcc -D_FORTIFY_SOURCE=1
はコンパイル時にのみチェックを追加します(#include <string.h>
としていくつかのヘッダーが必要です)gcc -D_FORTIFY_SOURCE=2
は実行時にチェックも追加します(バッファーオーバーフローが検出されるとプログラムが終了します)基本的に、_FORTIFY_SOURCE
レベル2はより安全ですが、少し危険なコンパイル戦略です。使用する場合は、コンパイルしたコードに対して非常に強力な回帰テストを行い、コンパイラが予期しない動作を引き起こしていないことを確認してください。
http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html は feature_test_macros(7)
よりも詳細になります。
関連する抜粋は、わかりやすくするために軽く編集/再フォーマットされています。
_
-D_FORTIFY_SOURCE=1
_と_-D_FORTIFY_SOURCE=2
_の違いは、たとえばために_struct S { struct T { char buf[5]; int x; } t; char buf[20]; } var;
__
-D_FORTIFY_SOURCE=1
_を使用すると、_strcpy (&var.t.buf[1], "abcdefg");
__
-D_FORTIFY_SOURCE=2
_の場合、オーバーフローと見なされません(オブジェクトはVAR
全体)_strcpy (&var.t.buf[1], "abcdefg");
_バッファオーバーフローと見なされます。
別の違いは、最も一般的な_
-D_FORTIFY_SOURCE=2
_ファミリー関数のフォーマット文字列の_%n
_、_*printf
_では、読み取り専用メモリ(通常は文字列リテラル、gettext
の_("%s string %n")
も問題ありませんが)、通常、攻撃者がフォーマット文字列の脆弱性を悪用しようとすると、_%n
_は攻撃者が書き込むことができる場所になります。