更新 : 2007 年 11 月
TypeName |
UseSafeHandleToEncapsulateNativeResources |
CheckId |
CA2006 |
カテゴリ |
Microsoft.Reliability |
互換性に影響する変更点 |
なし |
原因
マネージ コードが IntPtr を使用してネイティブ リソースにアクセスしています。
規則の説明
マネージ コードで IntPtr を使用すると、セキュリティ上の問題および信頼性の問題が発生する可能性があります。すべての IntPtr の使用状況をチェックして、SafeHandle または類似のテクノロジに置き換える必要があるかを判断してください。IntPtr が、マネージ コードの所有と見なされるメモリ、ファイル ハンドル、ソケットなどのネイティブ リソースを表す場合に問題が発生します。マネージ コードはリソースを解放することになっているので、失敗するとリソース リークが発生します。
このシナリオでは、IntPtr や、IntPtr によって表されているリソースを解放する方法への、マルチスレッド アクセスが許可されていると、セキュリティ上の問題や信頼性の問題も発生します。これらの問題は、リソース解放時にそのリソースが別のスレッドで同時に使用されている場合に生じる IntPtr 値のリサイクルが関連しています。このリサイクルから競合状態が発生し、片方のスレッドが、誤ったリソースに関連付けられたデータを読み書きする可能性があります。たとえば、OS ハンドルを IntPtr として型に格納し、ユーザーがそのハンドルを使って Close と他の任意のメソッドを同期させずに同時に両方とも呼び出す場合に、コードでハンドルのリサイクル問題が発生します。
ハンドルのリサイクル問題によって、データが破損したり、セキュリティ上の脆弱性が生じたりします。このようなスレッド問題を回避するために、SafeHandle およびその兄弟クラス CriticalHandle は、ネイティブ ハンドルをリソースにカプセル化する機構を提供します。また、SafeHandle および兄弟クラス CriticalHandle は、他のスレッド問題にも使用できます。たとえば、ネイティブ メソッドの呼び出しに対するネイティブ ハンドルのコピーを格納するマネージ オブジェクトの有効期間を綿密に制御できます。この場合、通常は GC.KeepAlive の呼び出しを削除します。SafeHandle や CriticalHandle (使用頻度は少ない) を使用すると、パフォーマンス オーバーヘッド が必然的に発生しますが、注意深い設計によって低減できます。
違反の修正方法
IntPtr の使用を SafeHandle に変更して、ネイティブ リソースへのアクセスを安全に管理します。
警告を抑制する状況
この警告は抑制しないでください。