CRT のセキュリティ機能
多くの旧来の CRT 関数に、新しくセキュリティが強化されたバージョンができました。 セキュリティが強化された関数が存在する場合、セキュリティが弱い古いバージョンは推奨されないバージョンとしてマークされ、新しいバージョンには _s ("secure") のサフィックスが付いています。
ここで、"推奨されない" とは、その関数が CRT から削除される予定だということではありません。
また、セキュリティが強化された関数は、セキュリティ エラーを防止したり訂正したりするのではなく、エラー発生時にそのエラーをキャッチします。 これらの関数はエラー条件をチェックし、エラーが発生した場合に、エラー ハンドラーを呼び出します (「パラメーターの検証」を参照)。
たとえば、strcpy 関数は、コピーする文字列が大きすぎてコピー先のバッファーに入らない場合、これを通知する手段を持ちません。 ただし、セキュリティが強化されたバージョンの strcpy_s では、バッファーのサイズをパラメーターとして取り、バッファー オーバーランが発生するかどうかを事前に判断できます。 strcpy_s を使用して、11 文字を 10 文字バッファーにコピーしようとすると、これはエラーになります。strcpy_s でこの間違いを訂正することはできませんが、このエラーを検出して、無効なパラメーター ハンドラーを呼び出すことにより、エラーの発生を通知できます。
使用されなくなったことを知らせる警告の除去
セキュリティが弱い古い関数に対する警告を除去するための方法はいくつかあります。 一番簡単な方法は、_CRT_SECURE_NO_WARNINGS を定義するか、warning プラグマを使用する方法です。 どちらの方法でも警告は無効になりますが、その警告の原因になったセキュリティの問題はもちろんそのまま存在します。 使用されなくなったことを知らせる警告は有効にしたままにして、新しい CRT セキュリティ機能を利用することを推奨します。
C++ における最も簡単な方法はセキュリティ保護されたテンプレート オーバーロードを使用する方法です。多くの場合、この方法で、推奨されない関数の呼び出しが、セキュリティが強化された新しいバージョンの呼び出しに置き換えられるので、非推奨警告は表示されません。 たとえば、推奨されない strcpy 関数の呼び出しを次に示します。
char szBuf[10];
strcpy(szBuf, "test"); // warning: deprecated
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES を 1 として定義すると、strcpy の呼び出しが、バッファー オーバーランを防ぐ strcpy_s の呼び出しに変更され、警告は除去されます。 詳細については、「セキュリティ保護されたテンプレート オーバーロード」を参照してください。
セキュリティ保護されたテンプレート オーバーロードがない推奨されない関数の場合、セキュリティが強化されたバージョンを使用するように手動でコードを更新することを強くお勧めします。
セキュリティには関連しませんが、使用されなくなったことを知らせる警告が発生する別の要因として、POSIX 関数があります。 POSIX の関数名を標準に沿った名前に置き換えるか (access を _access にするなど)、_CRT_NONSTDC_NO_WARNINGS を定義して、POSIX 関連の使用されなくなったことを知らせる警告を無効にします。 詳細については、「使用を推奨されていない CRT 関数」を参照してください。
追加されたセキュリティ機能
導入されたセキュリティ機能の例を次に示します。
Parameter Validation. セキュリティが強化された関数、および多くの既存の関数の両方について、CRT 関数に渡されるパラメーターが検証されます。 次のような検証が行われます。
関数に渡された NULL 値のチェック。
列挙値が有効であるかどうかのチェック。
整数値が有効な範囲にあるかどうかのチェック。
詳細については、「パラメーターの検証」を参照してください。
無効なパラメーターのハンドラーを開発者自身が利用できるようになりました。 無効なパラメーターが検出された場合に、アプリケーションをアサートしたり終了したりすることなく、_set_invalid_parameter_handler 関数でこれらの問題をチェックできます。
Sized Buffers. セキュリティが強化された関数では、バッファーへの書き込みを行うすべての関数に対してバッファー サイズが渡される必要があります。 セキュリティが強化されたバージョンでは、書き込み前にバッファーのサイズを確認して、悪意のあるコードが実行される余地を与える危険なバッファー オーバーラン エラーを回避する役割を果たします。 これらの関数は、通常、errno 型のエラー コードを返し、バッファーのサイズが小さすぎる場合、無効なパラメーター ハンドラーを呼び出します。 gets など、入力バッファーからの読み込みを行う関数のセキュリティが強化されたバージョンでは、最大サイズを指定する必要があります。
Null termination. 文字列に終端文字を設定しない可能性のある関数のいくつかには、確実に文字列を null で終わらせるバージョンがセキュリティ強化バージョンとして追加されています。
Enhanced error reporting. セキュリティが強化された関数では、既存の関数より詳細なエラー情報が含まれるエラー コードが返されます。 現在、セキュリティが強化された関数と多くの既存の関数は、errno を設定し、通常、より詳細なエラー情報を提供する errno コード型も返します。
Filesystem security. セキュリティが強化されたファイル I/O API では、安全なファイル アクセスを既定でサポートします。
Windows security. セキュリティが強化されたプロセス API ではセキュリティ ポリシーが適用され、ACL を指定できます。
Format string syntax checking. 無効な文字列が検出されます。たとえば、 printf 書式指定文字列の不正な型フィールド文字を使用した場合です。